Xamarin Forms Picker绑定不同模型属性的实现咨询
Got it, let's fix this issue for you. The core problem here is that your Contact.Type is a string (the Code value you want to store), but the Picker's SelectedItem expects a MyType instance—so the types don't match, which breaks the binding. Here are two solid, practical solutions to handle this:
Solution 1: Use a Value Converter
This approach creates a converter to translate between MyType objects and their Code strings, allowing direct two-way binding between Contact.Type and the Picker's selected item.
Create the converter class
ImplementIValueConverterto handle the type translation:public class MyTypeToCodeConverter : IValueConverter { // Convert a MyType instance to its Code string (for the bound Contact.Type) public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value is MyType myType ? myType.Code : null; } // Convert a Code string back to the matching MyType from your collection public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value is string code && parameter is ObservableRangeCollection<MyType> typeCollection) { return typeCollection.FirstOrDefault(t => t.Code == code); } return null; } }Update your XAML
First, declare the converter in your page's resources, then fix the Picker bindings (note: your originalItemsSourcehad a syntax error—corrected below):<ContentPage.Resources> <!-- Replace "local:" with your actual namespace --> <local:MyTypeToCodeConverter x:Key="MyTypeToCodeConverter" /> </ContentPage.Resources> <Picker x:Name="TypePicker" Title="Please select a type.." ItemsSource="{Binding Types}" ItemDisplayBinding="{Binding Description}" SelectedItem="{Binding Contact.Type, Converter={StaticResource MyTypeToCodeConverter}, ConverterParameter={Binding Types}, Mode=TwoWay}" />
Solution 2: Use a ViewModel Middle Property
This method uses a dedicated property in your ViewModel to hold the selected MyType instance, then updates Contact.Type automatically when the selection changes. It’s often simpler for beginners to follow.
Add the middle property to your ViewModel
Assuming your ViewModel implementsINotifyPropertyChanged:private MyType _selectedMyType; public MyType SelectedMyType { get => _selectedMyType; set { if (_selectedMyType != value) { _selectedMyType = value; OnPropertyChanged(); // Sync the Code value to Contact.Type Contact.Type = value?.Code; } } } // Optional: Sync Picker selection when Contact is loaded/updated private Contact _contact; public Contact Contact { get => _contact; set { if (_contact != value) { _contact = value; OnPropertyChanged(); // Set Picker selection if Contact.Type has a value if (!string.IsNullOrEmpty(value?.Type)) { SelectedMyType = Types.FirstOrDefault(t => t.Code == value.Type); } } } }Update the Picker XAML
BindSelectedItemto the new ViewModel property instead ofContact.Type:<Picker x:Name="TypePicker" Title="Please select a type.." ItemsSource="{Binding Types}" ItemDisplayBinding="{Binding Description}" SelectedItem="{Binding SelectedMyType, Mode=TwoWay}" />
A quick note on your original XAML: The ItemsSource binding had a typo ({Binding MyType}, Mode=TwoWay}) — it should be {Binding Types}, and Mode=TwoWay isn’t necessary here since ObservableRangeCollection already notifies the UI of changes.
内容的提问来源于stack exchange,提问作者the_tr00per

