2

I have what I believe is a pretty straightforward Monotouch.Dialog class.

public partial class EditAccountDialog : DialogViewController
{
    Section emailSection;
    Section passwordSection;
    Section profileSection;
    Section addressSection;

    EntryElement emailEntry;
    EntryElement passwordEntry;
    EntryElement password2Entry;
    EntryElement firstNameEntry;
    EntryElement lastNameEntry;
    EntryElement phoneNumberEntry;
    EntryElement streetEntry;
    EntryElement street2Entry;
    EntryElement cityEntry;
    EntryElement stateEntry;
    EntryElement zipEntry;

    public EditAccountDialog(bool pushing) : base (UITableViewStyle.Grouped, null, pushing)
    {
        emailEntry = new EntryElement(null, "example@domain.com", String.Empty);
        passwordEntry = new EntryElement (null, "Password", String.Empty, true);
        password2Entry = new EntryElement (null, "Re-enter password", String.Empty, true);
        firstNameEntry = new EntryElement ("First Name", "First Name", String.Empty);
        lastNameEntry = new EntryElement ("Last Name", "Last Name", String.Empty);
        phoneNumberEntry = new EntryElement ("Phone Number", "###-###-####", String.Empty);
        streetEntry = new EntryElement ("Street", "#### Any St.", String.Empty);
        street2Entry = new EntryElement ("Street 2", "Apt #", String.Empty);
        cityEntry = new EntryElement ("City", "City", String.Empty);
        stateEntry = new EntryElement ("State", "State", String.Empty);
        zipEntry = new EntryElement ("ZIP Code", "#####", String.Empty);

        emailSection = new Section ("Email"){
            emailEntry,
        };

        passwordSection = new Section ("Password"){
            passwordEntry,
            password2Entry,
        };

        profileSection = new Section("Profile") {
            firstNameEntry,
            lastNameEntry,
            phoneNumberEntry,
        };

        addressSection = new Section("Address") {
            streetEntry,
            street2Entry,
            cityEntry,
            stateEntry,
            zipEntry,
        };

        Root = new RootElement("Edit Account") {
            emailSection,
            passwordSection,
            profileSection,
            addressSection,
        };
    }

    public virtual void HandleGetAccountResponse(GetAccountResponse response)
    {
        emailEntry.Value = response.Email;
        firstNameEntry.Value = response.FirstName;
        lastNameEntry.Value = response.LastName;
        phoneNumberEntry.Value = response.Phone;
        streetEntry.Value = response.StreetAdd;
        street2Entry.Value = response.StreetAdd2;
        cityEntry.Value = response.City;
        stateEntry.Value = response.State;
        zipEntry.Value = response.Zip;
    }
}

After the page loads, I asynchronously call a REST API for existing account information, which then calls HandleGetAccountResponse above to pre-populate every EntryElement in the Dialog.

I inspect the REST response and know that I am receiving all of the necessary data. The problem that I am running into is that one or two random cells on this page appear to be blank, even after their values have been set. For example, the Zip and City fields might appear to be blank.

What is even more confusing is that, if I scroll to the bottom and see that the Zip and City fields are blank, then scroll all the way back up, then scroll to the bottom again, a different set of cells might be blank, such as Street2 and State.

Obviously this isn't normal behavior for Monotouch.Dialog or no one would use it. What can I do to resolve this problem?

pdusen
  • 520
  • 2
  • 7
  • 18
  • Are only the cell values empty, or are the labels empty too? Your best bet is probably to use the MT.D source (from github) and debug that. Or if you can come up with an isolated test case, submit a bug to Xamarin. – Jason Dec 05 '12 at 12:51
  • The values aren't empty, they just aren't visible on the screen. I should have clarified in the question title. – pdusen Dec 05 '12 at 14:13
  • that sounds like a possible bug in MT.D - I'd submit it to Xamarin if you can create an isolated test case – Jason Dec 05 '12 at 16:08
  • I came up with one and submitted it to them yesterday, but have yet to hear back. – pdusen Dec 06 '12 at 16:13
  • This typically happens when you have different types of cells reusing the same reusableIdentifierKey, but it seems like all of your elements are EntryElements, though, so that shouldn't be a problem. – jstedfast Dec 06 '12 at 23:12

3 Answers3

1

I bet the problem is caused by the Password EntryElements using the same "CellKey" ("reusableIdentifier" in Objective-C lingo) as the other entry elements.

As a workaround, I would suggest subclassing EntryElement like so:

public class PasswordEntryElement : EntryElement
{
    static readonly NSString PasswordEntryElementCellKey = new NSString ("PasswordEntryElement");

    public PasswordEntryElement (string caption, string placeholder, string value) : base (caption, placeholder, value, true)
    {
    }

    protected override NSString CellKey {
        get { return PasswordEntryElementCellKey; }
    }
}

If this works, then it's a bug in MonoTouch.Dialog (I'll submit a pull request to the official MonoTouch.Dialog github project once you can confirm that this works for you).

The problem is that each type of cell really needs to have its own "CellKey" if they are configured differently. Since the passworded EntryElements use differently configured UITextFields, this might be the cause of your problem.

Helpful Hint: If you encounter this type of problem, where some cells are blank, almost always it is due to the multiple types of cells reusing the same CellKey. In your case, you had 2 cells that would typically be invisible - that is a strong indication that there were 2 elements that were not like the others (which is what led me toward the Password elements).

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • I'll give this a try, but it was never the password elements that were blank (as far as I could tell, at least). It was always one of the cells in the bottom-most section. – pdusen Dec 07 '12 at 14:36
  • This is interesting... switching the password elements to the subclass you suggested eliminated ONE of the blank elements, but there is still always one showing up. Do you have any other suggestions? – pdusen Dec 07 '12 at 14:46
  • I dunno, maybe the emailEntry because you set the caption to null? Btw, the elements that are blank (or aren't blank) are not necessarily related to which cells are causing the problem, all you can rely on are the # of blank cells. – jstedfast Dec 07 '12 at 17:33
1

Based on a test sample that was sent back to me by Xamarin engineers, I was ultimately able to solve this problem by changing the following lines:

    emailEntry = new EntryElement(null, "example@domain.com", String.Empty);
    passwordEntry = new EntryElement (null, "Password", String.Empty, true);
    password2Entry = new EntryElement (null, "Re-enter password", String.Empty, true);

To this:

    emailEntry = new EntryElement(" ", "example@domain.com", String.Empty);
    passwordEntry = new EntryElement (" ", "Password", String.Empty, true);
    password2Entry = new EntryElement (" ", "Re-enter password", String.Empty, true);

Please note that is a string with exactly one space. I tried doing it with String.Empty or just an empty string like "", which is the more intuitive idea, but they exhibit the same problem.

pdusen
  • 520
  • 2
  • 7
  • 18
0

pdusen, try place InvokeOnMainThread(ReloadData) after model update in HandleGetAccountResponse. Hope this help!

  • Another person posted this same answer, but seems to have removed it. As I told them, this does not solve the problem. Also, please note that most of the fields above do show the received profile data; only a random handful appear blank. – pdusen Dec 04 '12 at 22:35