在DataGrid
中,我希望ComboBoxColumn
的每行具有相同的内容。ComboBox
的内容是动态的:如果您在ComboBox
中为一行选择了一个值,则此选定值不能为其他行选择。我目前的问题是ComboBox
的内容在前面的几行中没有更新。我举了一个简单的例子来解释:
XAML
<StackPanel>
<DataGrid ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Height="auto"
CanUserAddRows="False"
AutoGenerateColumns="False"
IsReadOnly="False">
<DataGrid.Columns>
<DataGridTemplateColumn Width="*" Header="Key" MinWidth="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.KeyList, RelativeSource={RelativeSource Findancestor, AncestorType={x:Type Window}}}"
SelectedItem="{Binding SelectedKey, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding IsSelectable}"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Value" Binding="{Binding Value, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<Button Margin="0,10,0,0" Width="80" Content="Add Row" Command="{Binding AddRowCommand}"/>
</StackPanel>
主虚拟机
public class MainVM
{
private ObservableCollection<ItemsVM> myItems;
private List<Key> myKeyList = new List<Key>()
{
new Key("Item 1", true),
new Key("Item 2", true),
new Key("Item 3", true)
};
public MainVM()
{
myItems = new ObservableCollection<ItemsVM>();
AddRowCommandAction();
}
public ObservableCollection<ItemsVM> Items => myItems;
public ItemsVM SelectedItem { get; set; }
public List<Key> KeyList => myKeyList;
private void SetKeySelectability()
{
foreach (Key item in myKeyList)
{
if (myItems.Any(x => x.SelectedKey == item))
item.IsSelectable = false;
else
item.IsSelectable = true;
}
}
private RelayCommand myAddRowCommand;
public RelayCommand AddRowCommand
{
get
{
if (myAddRowCommand == null)
myAddRowCommand = new RelayCommand(AddRowCommandAction);
return myAddRowCommand;
}
}
private void AddRowCommandAction()
{
myItems.Add(new ItemsVM
{
Value = string.Format("Row {0}", myItems.Count + 1),
SelectedKey = myKeyList.FirstOrDefault(x => x.IsSelectable == true)
});
SetKeySelectability();
}
}
其他类别
public class ItemsVM
{
public string Value { get; set; }
public Key SelectedKey { get; set; }
}
public class Key : ObservableObject
{
private bool _IsSelectable;
public Key(string name, bool isselectable)
{
Name = name;
IsSelectable = isselectable;
}
public string Name { get; set; }
public bool IsSelectable
{
get { return _IsSelectable; }
set
{
if (_IsSelectable == value) return;
_IsSelectable = value;
OnPropertyChanged(nameof(IsSelectable));
}
}
}
在开始时,我们可以看到Item 1
被选择为Row 1
,Item 1
IsSelectable
属性被更新并且不再可选:
在点击Button
添加一行后,我得到了这个(这是正确的)。两个使用的值不可选,Row 1's
ComboBox
具有相同的值。
现在,我更改Row 1
的值:我们可以看到,Item 1
是不可选择的(但它应该是),Row 2's
ComboBox
也不是最新的(Item 3
是可选择的,不应该和Item 1
没有发布)
我如何才能做到这一点?
1条答案
按热度按时间lp0sw83n1#
如果我理解正确的话,要做到这一点,需要在ComboBox的选中项发生变化时,更新Key示例的IsSelectable属性。
在您的情况下,每当SelectedKey更改时,您需要从ItemsVM类中引发PropertyChanged事件。需要通知MainVM更新Key示例的IsSelectable属性。
以下是你可以做的:
1.使ItemsVM类实现INotifyPropertyChanged:
1.在MainVM类中,订阅ItemsVM示例的PropertyChanged事件:
1.将ItemPropertyChanged方法添加到MainVM以处理事件:
1.最后,在适当的时候取消订阅PropertyChanged事件,以避免内存泄漏。例如,您可能会在某个时候从myItems中删除ItemsVM示例,并且您需要在执行此操作之前取消订阅: