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>
      
      <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();

Sign In or Register to comment.