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

MAUI中CollectionView内Picker无法预选中绑定值的问题

问题:Picker无法预选中已关联的分类项

我尝试建立Milestones和Categories两个Observable Collection的关联,具体实现如下:

Milestone模型定义SelectedCategory属性

public Category SelectedCategory
{
    get => selectedCategory;
    set
    {
        if (selectedCategory != value)
        {
            selectedCategory = value;
            OnPropertyChanged(nameof(SelectedCategory));
        }
    }
}

后台代码为每个Milestone设置关联分类

foreach (var m in Milestones)
{
    m.SelectedCategory = Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);
}

XAML布局代码

<CollectionView Grid.Row="1" Margin="25,10,0,0" ItemsSource="{Binding Milestones}" VerticalOptions="FillAndExpand">
    <CollectionView.ItemTemplate>
        <DataTemplate>
                <Picker Grid.Column="2"
                ItemsSource="{Binding Path=BindingContext.Categories, Source={RelativeSource AncestorType={x:Type local:ModifyProjectPage}}}"
                ItemDisplayBinding="{Binding CategoryName}"
                SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" />   
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

目前的问题是:Picker能正常显示所有分类名称,用Label绑定SelectedCategory.CategoryName也完全正常,但无法预选中已设置的SelectedCategory;如果去掉Source={RelativeSource ...},Picker的ItemsSource绑定会失效。


解决方案

问题根源是Picker判断SelectedItem是否匹配时,默认用的是对象引用相等。如果你的Category实例是从不同来源加载的(比如数据库查询后重新实例化,或者Categories集合和赋值用的实例不是同一批),即使IdCategory相同,引用不同也会导致Picker无法识别匹配项。

解决方法有两种:

  1. 重写Category类的Equals和GetHashCode方法,让比较基于IdCategory:
public class Category
{
    public int IdCategory { get; set; }
    public string CategoryName { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is Category other)
        {
            return IdCategory == other.IdCategory;
        }
        return false;
    }

    public override int GetHashCode()
    {
        return IdCategory.GetHashCode();
    }
}
  1. 确保SelectedCategory是Categories集合中的同一个实例
    如果Categories是ObservableCollection,赋值时直接从集合中获取实例,避免创建新的对象:
// 确保Categories集合已经加载完成
foreach (var m in Milestones)
{
    m.SelectedCategory = Categories.FirstOrDefault(c => c.IdCategory == m.IdCategory);
    // 这里要保证Categories里的实例和你赋值的是同一个,比如不要重新new Category
}

额外检查点:

  • 确认后台赋值后,Milestone的SelectedCategory确实不为null
  • 确认Categories集合中存在IdCategory匹配的项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:42:37