我正在研究
WPF应用程序并关注MVVM.在我看来,有一个包含不同列的网格视图.其中一列是ListBox.现在的问题是,对于ListBox列,SelectedItem get工作正常但set没有.
这是我的View代码
<DataGrid ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" SelectionMode="Single"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Name}" Header="Name" /> <DataGridTemplateColumn Header="Actions"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ListBox DisplayMemberPath="Name" ItemsSource="{Binding Actions}" SelectedItem="{Binding SelectedAction}" /> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
在我的viewmodel中,我有Main viewmodel类,其中包含Items列表. Item类包含name,操作列表和所选操作.
public class Myviewmodel : INotifyOfPropertyChanged { private ObservableCollection<Item> _items; public ObservableCollection<Item> Items { get { return _items?? (_items= new ObservableCollection<Item>); } } private Item _selectedItem; public Item SelectedItem { get { return _selectedItem; } set { _selectedItem= value; } } } public class Item : INotifyOfPropertyChanged { public string Name; private ObservableCollection<string> _actions; public ObservableCollection<string> Actions { get { return _actions?? (_actions= new ObservableCollection<string>); } } private string _selectedAction; public string SelectedAction { get { return _selectedAction; } set { _selectedAction = value; } } }
现在SelectedItem for Items列表工作正常.但是SelectedItem insde为Actions的Item类不起作用.我在SelectedAction的getter和setter上插入了断点.得到断点命中.但是如果我从UI中选择一个动作,那么为SelectedAction设置断点就不会被击中.
有什么问题.
当我选择Archive Project或Restore Project时,不会调用SelectedAction的setter.
注意:我删除了不必要的信息,如在列表中加载数据,实现INotifyOfPropertyChanged等.
解决方法
我不知道是不是你的情况,但既然你说你已经削减了一些信息我会尽力回答.
当我将一个custum模板添加到ListBox或ListView并且ListBoxItem中的控件处理click事件时,这种情况发生在我身上.
例如,如果您有这样的单选按钮
<ListBox ItemsSource="{Binding List}" SelectedItem="{Binding item}"> <ListBox.ItemTemplate> <DataTemplate> <RadioButton Content="{Binding Name}" GroupName="groupName"> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
当您实际单击单选按钮时,将不会设置SelectedItem,因为单选按钮将处理单击事件并且不会将其冒泡,因此ListBox可能会更改它的选择.
您必须确保ListBox获取事件并且模板中的控件会相应地做出反应.在这种情况下,你将不得不做这样的事情.
<ListBox ItemsSource="{Binding List}" SelectedItem="{Binding Item}"> <ListBox.ItemTemplate> <DataTemplate> <RadioButton Content="{Binding Name}" IsHitTestVisible="False"> <RadioButton.Style> <Style TargetType="{x:Type RadioButton}"> <Setter Property="IsChecked" Value="{Binding Path=IsSelected,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBoxItem}}}" /> </Style> </RadioButton.Style> </RadioButton> </DataTemplate> </ListBox.ItemTemplate> </ListBox>