1
votes

I've got a picker on the screen, that has an initial value, as well as the option to change the item in the picker.

While my selectedItem is set, I don't see that on the picker on the screen, the picker has no value set, and it's not until I select a value, that it actually displays something in the picker on the screen (At this time the SelectedItem is also updated with the new value).

My xaml:

    <Picker
       ItemsSource="{Binding FeedbackTypes}"
       SelectedItem="{Binding SelectedFeedbackType, Mode=TwoWay}"
       ItemDisplayBinding="{Binding Name}">
   </Picker>

My ViewModel properties:

private ValueName _selectedFeedbackType;

public ValueName SelectedFeedbackType
{
  get { return _selectedFeedbackType; }

  set
  {
    _selectedFeedbackType = value;
    OnPropertyChanged(nameof(SelectedFeedbackType));
  }
}

public ObservableCollection<ValueName> FeedbackTypes
{
  get
  {
    var feedbackTypes = new ObservableCollection<ValueName>();

    foreach (FeedbackType feedback in 
             Enum.GetValues(typeof(FeedbackType)))
    {
      feedbackTypes.Add(new ValueName
      {
        Value = feedback,
        Name = feedback.ToName()
       });
     }

   return feedbackTypes;
  }
}

And in my ViewModel constructor I've got:

SelectedFeedbackType = new ValueName { Value = feedbackType, Name = feedbackType.ToName() };

The constructor works sets the SelectedFeedbackType correctly and if I don't make any changes to the picker, that is the value I get in there on submit, however, I do not see that value in the picker by default. The picker is empty until a selection is made.

I've also tried to bind the SelectedIndex value to the SelectedFeedbackType, however that one will not show the initially selected value either in the picker.

1
I'm not completely sure if the selecteditem needs to be present in the items list but I suspect it does. So then the question is how you implemented the equality check for ValueName. My assumption is that even with the same values for Value and Name the objects are not viewed as equal (and rightfully so if they're objects) and therefor the picker might be unable to select the right one from the list. Not sure though, just a thought:-)Knoop
You are right, I assumpted because the SelectedItem, is an item from the data source, you have to use the entire selectedItem to do the comparison. But it looked like only looking at the value: SelectedIndex="{Binding SelectedFeedbackType.Value}" does the trick.Lex
Well this seems like a bit of a roundabout way to do this. I believe this only works because the values of an enum number from 0 and onwards by default (so they map with the indices). But as soon as someone where to adjust the values of your enum, this part of your code would probably break, which makes it too fragile imo. However I don't have time to test this atm so this is purely theoretical.Knoop
I know, the values will never change, but until Xamarin has a nice way to tie a list of enums (using their display attribute as the display name), This is the only way I got it working in the latest version of Xamarin, using .net standard.Lex
I don't think the problem is with the enum, but more with the ValueName class. I think I would've gone for a solution that either in the setter of SelectedFeedbackType does a _selectedFeedbackType = FeedBackTypes.FirstOrDefault(fbt => fbt.Value == value?.Value); or, probably the better solution, implement the IEquatable interface on your ValueName class.Knoop

1 Answers

0
votes

You could try to set defalut value of the Xamarin Picker. You just set the selectedIndex(the first number of index is 0) of your picker like the following code.

Mypicker.SelectedIndex=1;

There is a code of demo.

GIF of demo when first running. enter image description here

You can download this demo by the link. https://developer.xamarin.com/samples/xamarin-forms/UserInterface/PickerDemo/

Then changed the code of MonkeysPage.xaml.

 <Picker x:Name="Mypicker" Title="Baboon" ItemsSource="{Binding Monkeys}" ItemDisplayBinding="{Binding Name}" SelectedItem="{Binding SelectedMonkey}" />

Add the defaule value of Pickerin MonkeysPage.xaml.cs.

    public MonkeysPage()
    {
        InitializeComponent();
        BindingContext = new MonkeysPageViewModel();
        Mypicker.SelectedIndex=1;

    }
}