我有一个item控件,它将使用来自ObservableCollection TrayTypesDataGrids的数据填充datagrids
private ObservableCollection<TrayTypeDataGrid> trayTypesDataGrids;
public class TrayTypeDataGrid : ViewModelBase
{
private ObservableCollection<TrayType> trayTypes;
public ObservableCollection<TrayType> TrayTypes
{
get => trayTypes;
set
{
trayTypes = value;
OnPropertyChanged(nameof(TrayTypes));
}
}
private ICommand selectionChangedCommand;
public ICommand SelectionChangedCommand
{
get
{
return selectionChangedCommand ?? (selectionChangedCommand = new CommandHandler((param) => SelectionChanged(param), true));
}
}
public TrayTypeDataGrid(ObservableCollection<TrayType> trayTypes)
{
this.trayTypes = trayTypes;
}
private void SelectionChanged(object args)
{
TrayType SelectedTrayType = ((TrayType)((SelectionChangedEventArgs)args).AddedItems[0]);
}
}
<ItemsControl x:Name="DataGridControl" ItemsSource="{Binding TrayTypesDataGrids}" HorizontalAlignment="Center" DockPanel.Dock="Top">
<ItemsControl.Template>
<ControlTemplate>
<DockPanel IsItemsHost="True" Height="{Binding Path=ActualHeight, ElementName=DataGridControl}"/>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid Style="{StaticResource DataGridStyleDetails}" ItemsSource="{Binding TrayTypes}">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}" ElementStyle="{StaticResource TBColumn}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" ElementStyle="{StaticResource TBColumn}"/>
<DataGridTextColumn Header="D" Binding="{Binding D}" ElementStyle="{StaticResource TBColumn}"/>
<DataGridTextColumn Header="W" Binding="{Binding W}" ElementStyle="{StaticResource TBColumn}"/>
</DataGrid.Columns>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" >
<i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这样就可以正确填充所有的DataGrid,并且SelectionChanged会获取TrayTypeDataGrid类中的行。但是,我想在选择更改时捕获,并从ItemControl中选择每个DataGrid上的匹配行。如何从ItemControl访问这些DataGrid并设置其选定行或更改匹配行的背景?
我认为这在MVVM中是不可能的,对吗?
1条答案
按热度按时间zxlwwiss1#
这里的主要挑战是WPF
MultiSelector
的(DataGrid
继承的)SelectedItems
属性不是DependencyProperty
。这使得直接绑定是不可能的。有很多黑客可以绕过这个问题。这个问题有几个答案可以引导你走向正确的方向,但没有一个提供了一个完整的解决方案,我会赞同,所以我不会简单地宣布这是一个重复:
Bind to SelectedItems from DataGrid or ListBox in MVVM
Brian Hinchey的答案-它子类化了
DataGrid
并添加了一个new SelectedItems
属性,我认为这是最接近的,但并不完整,因为它不允许通过绑定设置选择(只能检索它)。要处理设置,您需要在声明新的SelectedItems
DP时通过回调PropertyMetadata
来处理属性更改,如下所示:(You还需要确保您的DP更改处理程序不会在
OnSelectionChanged
处理程序期间执行,该处理程序由UI引起的选择更改触发,因此使用了_isUISelectionChangePending
技巧)。如果你能做到这一点,那么事情就变得简单了:将每个
MyNewDataGridClass
(双向)绑定到视图模型上的IList SelectedItems
属性。如果设置正确,任何网格上的UI引起的选择更改将传播到视图模型属性,然后返回到其他网格。