CollectionView中Picker的SelectedItem绑定为何变为null?
问题原因
Picker的SelectedItem默认是双向绑定,当它尝试匹配选中项时,默认会用引用地址比较Colour对象。即使你的Player.ColorNav和ColorsPicker里的对象属性完全一致,只要绑定时机问题导致Picker初始化时无法找到匹配项,就会判定没有选中项,进而通过双向绑定把Player.ColorNav设为null。
修复方案
1. 给Colour类重写相等比较方法
基于唯一标识ColorId来判定两个Colour对象是否相等,这样即使引用不同,只要ColorId一致就能被Picker识别为匹配项:
public class Colour { public int ColorId { get; set; } public string Name { get; set; } = default!; public override bool Equals(object? obj) { return obj is Colour colour && ColorId == colour.ColorId; } public override int GetHashCode() { return HashCode.Combine(ColorId); } }
2. 给Player类实现INotifyPropertyChanged(推荐)
虽然不是直接解决当前问题,但能保证属性变更时绑定的通知机制正常,避免后续绑定异常:
using System.ComponentModel; using System.Runtime.CompilerServices; public class Player : INotifyPropertyChanged { private string _name = default!; private int _colorId; private Colour _colorNav = default!; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } public int ColorId { get => _colorId; set { _colorId = value; OnPropertyChanged(); } } public Colour ColorNav { get => _colorNav; set { _colorNav = value; OnPropertyChanged(); // 可选:同步更新ColorId,保持数据一致性 if (value != null) ColorId = value.ColorId; } } public event PropertyChangedEventHandler? PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
3. 显式指定Picker的双向绑定模式(可选)
虽然默认就是双向,但显式指定能避免绑定模式的潜在歧义:
<Picker Grid.Column="1" ItemsSource="{Binding ColorsPicker, Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}}" ItemDisplayBinding="{Binding Name}" SelectedItem="{Binding ColorNav, Mode=TwoWay}"/>
原理说明
重写Equals和GetHashCode后,Picker会基于ColorId来匹配选中项,不再依赖引用地址,彻底解决初始化时匹配失败导致的ColorNav置空问题。实现INotifyPropertyChanged则能让UI实时响应属性变更,保证数据绑定的双向同步正常工作。
内容的提问来源于stack exchange,提问作者luis_m
相关产品推荐
相关产品推荐

