如何在MVVM模式下修改SelectedIndex?
你说后台直接写 DemoList.SelectedIndex = 3; 能正常选中,但用MVVM绑定后,明明命令触发了(MessageBox都弹了),SelectedItem = 5; 却没让列表选中对应项,对吧?我帮你梳理下可能的问题点:
先把你的关键代码列出来,方便对照:
后台直接生效的代码
DemoList.SelectedIndex = 3;
你的MVVM相关代码
ViewModel部分:
private int _SelectedItem; public int SelectedItem { get { return _SelectedItem; } set { _SelectedItem = value; NotifyOfPropertyChange("SelectedItem"); } } public ICommand ChangeSelection { get; private set; } // 初始化命令 ChangeSelection = new DelegateCommand(Changing); public void Changing() { SelectedItem = 5; MessageBox.Show("something"); }
XAML绑定:
SelectedIndex="{Binding SelectedItem}"
先检查DataContext有没有设对!
这是最常见的坑!如果你的View(窗口/用户控件)没把DataContext绑定到你的ViewModel实例,那所有绑定都是白搭。你可以在XAML根元素里这么设:<Window.DataContext> <local:你的ViewModel类名 /> </Window.DataContext>或者在后台代码里写:
this.DataContext = new 你的ViewModel类名();确认
NotifyOfPropertyChange是不是真的生效了
你调用的这个方法得正确触发INotifyPropertyChanged的PropertyChanged事件才行。要是这个方法内部写错了(比如拼写错属性名、事件没正确触发),UI根本收不到属性变更的通知。标准的实现应该是这样的:public event PropertyChangedEventHandler PropertyChanged; protected void NotifyOfPropertyChange(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }另外,建议用
nameof(SelectedItem)代替硬写字符串,避免拼写错误:NotifyOfPropertyChange(nameof(SelectedItem));看看列表项够不够多!
你设的是SelectedItem = 5;,但列表的索引是从0开始的,也就是说你的列表得至少有6个项才行。如果列表总共才5个或者更少,设这个索引自然没效果,UI也不会变。绑定模式要不要显式指定?
虽然SelectedIndex默认是双向绑定,但有时候如果不小心设成了OneWay就会出问题。可以显式加上模式试试:SelectedIndex="{Binding SelectedItem, Mode=TwoWay}"有没有其他代码在捣乱?
比如是不是有别的地方在偷偷改SelectedIndex或者列表的数据源,导致选中状态被重置?你可以在SelectedItem的setter里加个断点,看看除了你的Changing方法外,还有没有其他代码在修改这个值。
内容的提问来源于stack exchange,提问作者Black Panther

