Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Picker setting Model property to null, instead of setting picker SelectedItem to value in Model

IanCazIanCaz USMember ✭✭

I've got a XF project using XAML & MVVM, developing in Visual Studio 2017. On one of my forms I've got a picker:
<Picker x:Name="pSite" Title="Site" SelectedItem="{Binding CurrentSite}" ItemsSource="{Binding SiteList}" HorizontalOptions="FillAndExpand">

The page binding is set to my view model, which has the properties of CurrentSite (which is the site the user has saved) and SiteList (which is the list of all possible sites). When I load this on my device(s) the picker shows no current selection.

To troubleshoot, I added a label bound to CurrentSite:
<Label VerticalTextAlignment="Center" Text="{Binding CurrentSite}"></Label>

This Label also shows no value. If I remove the SelectedItem="{Binding CurrentSite}" from the picker, the Label shows the correct value (as stored in the database).

When walking through the debugger (breakpoing on the setting for CurrentSite) I see where it correctly grabs the current value from the database, but it is immediately set again to null.

Any idea why this is setting my Model value to null?

I'm currently using Xamarin.Forms v2.3.4.247

Thanks,
Ian

Best Answer

Answers

  • IanCazIanCaz USMember ✭✭

    Created "slimmed down" sample project.

    In the XAML are two lines (one commented out) showing the two behaviors.

  • HunumanHunuman GBMember ✭✭✭✭

    @IanCaz said:
    Created "slimmed down" sample project.

    In the XAML are two lines (one commented out) showing the two behaviors.

    Hi @IanCaz

    Please try this:

    <StackLayout  Orientation="Horizontal">
        <Label>Site (should say HOME):</Label>
        <Label Text="{Binding Source={x:Reference pSite}, Path=SelectedItem}"></Label>
    </StackLayout>
    
    <StackLayout  Orientation="Horizontal">
        <Label VerticalTextAlignment="Center">Picker:</Label>
        <!-- Below maintains Model -->
        <Picker x:Name="pSite" Title="Site" ItemsSource="{Binding UserPrefs.ocList_Sites}"  />
    </StackLayout>
    

    Hope that helps,

    Tim

  • Amar_BaitAmar_Bait DZMember ✭✭✭✭✭

    SelectedItem="{Binding CurrentSite, Mode=TwoWay}"

  • IanCazIanCaz USMember ✭✭

    @nadjib said:

    SelectedItem="{Binding CurrentSite, Mode=TwoWay}"

    Mode=TwoWay causes the same result.

  • IanCazIanCaz USMember ✭✭

    @Hunuman said:

    @IanCaz said:
    Created "slimmed down" sample project.

    In the XAML are two lines (one commented out) showing the two behaviors.

    Hi @IanCaz

    Please try this:

    <StackLayout  Orientation="Horizontal">
      <Label>Site (should say HOME):</Label>
      <Label Text="{Binding Source={x:Reference pSite}, Path=SelectedItem}"></Label>
    </StackLayout>
    
    <StackLayout  Orientation="Horizontal">
      <Label VerticalTextAlignment="Center">Picker:</Label>
      <!-- Below maintains Model -->
      <Picker x:Name="pSite" Title="Site" ItemsSource="{Binding UserPrefs.ocList_Sites}"  />
    </StackLayout>
    

    Hope that helps,

    Tim

    Thanks for the reply! The picker is still not getting set on load to "HOME" which it should be & the model still appears to be getting set to "blank" since the picker isn't set.

  • HunumanHunuman GBMember ✭✭✭✭

    Hi @IanCaz

    That is so weird, might well be worth submitting a bug report.
    Anyway glad you got it sorted.

    When I looked at your question originally I did not notice that you were referring to the default value of the bound label at page load. My bad.

    You can find a general method for setting the default value of a views bound content property here.

    Tim

  • HermanEHermanE USMember ✭✭

    @IanCaz Thanks for posting your solution. That probably saved me a lot of time!

  • OverheadOverhead USMember ✭✭

    Thanks @IanCaz , finally got it working by changing the order of these two.

  • NShahNShah Member ✭✭

    I know this is an old question. Hopefully this will help someone else.

    The order of the tags shouldn't make a difference unless you are running into a race condition. Which would be quite odd in XAML.

    the issue most likely is,

    When you are attempting to set the default value, you need to set CurrentSite = to an object from SiteList. The problem is when you set CurrentSite to an object, which YOU know to be in the list. However, the runtime doesn't know that. To it, it's a brand new object that it doesn't know. so you need to connect that dot for the runtime.

    so something like this,

    CurrentSite = SiteList.Where(x => x.id == currentSiteFromDb.id).FirstOrDefault();

  • McAttackMcAttack Member ✭✭

    I know this is an old thread, but I came across it today and although it didn't help me I did find a solution and would like to provide what I found handles this.

    I'm resetting a picker by setting SelectedItem to null. It worked at one time, then stopped. When the page opens, it's null, but my guess is the selected index is also -1.

    If I set SelectedItem to null after posting the form, it threw a null object exception in the XAML. Those are fun to figure out, right?

    To handle this, I set the selected index to -1 first, then set SelectedItem to null.

Sign In or Register to comment.