You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将MAUI Picker绑定到ViewModel?解决初始选中与值同步问题

Xamarin.Forms Picker 绑定问题解决方案

问题场景

XAML 代码

<Picker x:Name="Title" SelectedItem="{Binding Title, Mode=TwoWay}"  ItemsSource="{Binding Titles}" ItemDisplayBinding="{Binding Text}" Title="Title" />
<Entry x:Name="Name" Text="{Binding Name}" Placeholder="Name" />

ViewModel 代码

public class Person
{
    public string Name { get; set; }
    public string Title { get; set; }

    List<SelectListItem> Titles = new(){
        new SelectListItem { Text = "Mister", Value="Mr" },
        new SelectListItem { Text = "Doctor", Value="Dr" }
        // 更多选项
    };
}

初始化数据

Person person = new() { Name = "Bill Jones", Title = "Mr" };

遇到的问题

  1. Picker 加载时无法默认选中Mr对应的选项;
  2. 更改 Picker 选项后,ViewModel 无法获取选中项的Value(需要存储值而非显示文本)。

不想用SelectedIndexChanged事件或复杂的INotifyPropertyChanged实现,希望有简洁方案。


解决方案

核心思路是将 Picker 的SelectedItem绑定到SelectListItem类型的属性,而非字符串类型的Title,同时通过属性同步维护Title字符串的值,一次性解决默认选中和值同步问题。

步骤1:调整 ViewModel 结构

推荐使用CommunityToolkit.Mvvm简化INotifyPropertyChanged实现,避免手动编写重复代码:

using CommunityToolkit.Mvvm.ComponentModel;

public class SelectListItem
{
    public string Text { get; set; }
    public string Value { get; set; }
}

public partial class Person : ObservableObject
{
    public string Name { get; set; }

    [ObservableProperty]
    private string _title;

    [ObservableProperty]
    private SelectListItem _selectedTitle;

    public List<SelectListItem> Titles { get; } = new()
    {
        new SelectListItem { Text = "Mister", Value="Mr" },
        new SelectListItem { Text = "Doctor", Value="Dr" }
    };

    public Person()
    {
        // 当Title赋值时,自动匹配对应的SelectedTitle
        TitleChanged += (_, e) =>
        {
            SelectedTitle = Titles.FirstOrDefault(t => t.Value == e.NewValue);
        };

        // 当SelectedTitle改变时,自动更新Title的值
        SelectedTitleChanged += (_, e) =>
        {
            if (e.NewValue != null)
                Title = e.NewValue.Value;
        };
    }
}

如果不想用第三方库,手动实现INotifyPropertyChanged的版本:

using System.ComponentModel;
using System.Runtime.CompilerServices;

public class SelectListItem
{
    public string Text { get; set; }
    public string Value { get; set; }
}

public class Person : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    private string _title;
    public string Title
    {
        get => _title;
        set
        {
            _title = value;
            OnPropertyChanged();
            SelectedTitle = Titles.FirstOrDefault(t => t.Value == value);
        }
    }

    private SelectListItem _selectedTitle;
    public SelectListItem SelectedTitle
    {
        get => _selectedTitle;
        set
        {
            _selectedTitle = value;
            OnPropertyChanged();
            if (value != null)
                Title = value.Value;
        }
    }

    public List<SelectListItem> Titles { get; } = new()
    {
        new SelectListItem { Text = "Mister", Value="Mr" },
        new SelectListItem { Text = "Doctor", Value="Dr" }
    };

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

步骤2:修改 XAML 绑定

将 Picker 的SelectedItem绑定到SelectedTitle属性:

<Picker x:Name="TitlePicker" 
        SelectedItem="{Binding SelectedTitle, Mode=TwoWay}" 
        ItemsSource="{Binding Titles}" 
        ItemDisplayBinding="{Binding Text}" 
        Title="Title" />
<Entry x:Name="NameEntry" Text="{Binding Name}" Placeholder="Name" />

步骤3:初始化数据

初始化时只需设置Title,SelectedTitle会自动匹配对应的选项:

Person person = new() { Name = "Bill Jones", Title = "Mr" };

方案优势

  • 无需处理SelectedIndexChanged事件,所有逻辑集中在 ViewModel 中,代码更整洁;
  • 多个 Picker 场景下,只需复用相同的属性结构,代码冗余度低;
  • 双向绑定自动生效,同时解决默认选中和值同步两个核心问题。

内容的提问来源于stack exchange,提问作者djack109

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:30:41