[英]WPF Select multiple items in DataGrid from ViewModel with twoway binding
我正在尝试创建到 WPF DataGrid
所选项目的双向绑定。 我希望能够从ViewModel
和实际的UserControl
选择多个项目。 我知道我无法直接设置所选项目,因为此属性是只读的。
我正在考虑绑定到DependencyProperty
并在后面的代码中订阅DataGrid
的SelectionChanged
事件。
<UserControl.Resources>
<Style TargetType="local:ListView">
<Setter Property="SelectedItems" Value="{Binding SelectedItemsVM, Mode=TwoWay}"/>
</Style>
</UserControl.Resources>
<DataGrid Name="ObjectListDataGrid" SelectionChanged="OnSelectionChanged">
在后面的代码中,我创建了DependencyProperty
。 设置后,我订阅了CollectionChanged
事件。
public ObservableCollection<object> SelectedItems
{
get { return (ObservableCollection<object>)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
}
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(ObservableCollection<object>), typeof(ListView), new PropertyMetadata(default(ObservableCollection<object>), OnSelectedItemsChanged));
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var collection = e.NewValue as ObservableCollection<object>;
if (collection != null)
{
collection.CollectionChanged -= OnSelectedItemsCollectionChanged;
collection.CollectionChanged += OnSelectedItemsCollectionChanged;
}
}
我使用EventHandler
到DataGrid
的SelectionChanged
事件来添加/删除集合中的项目。
private void OnSelectionChanged(object sender, SelectionChangedEventArgs args)
{
SelectedItems.Remove(args.RemovedItems);
SelectedItems.Add(args.AddedItems);
}
现在我想在集合更改时选择OnSelectedItemsCollectionChanged
方法中所需的行。
private static void OnSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
foreach (DataGridRow row in ObjectListDataGrid.Rows())
{
if(ObjectListDataGrid.SelectedItems.Contains(row.Item))
row.IsSelected = true;
else
row.IsSelected = false;
}
}
问题:由于OnSelectedItemsCollectionChanged
方法是静态的,我无权访问ObjectListDataGrid
。 有什么办法可以克服这个问题,或者以不同的方式做到这一点?
为了完整DataGrid.Rows()
, DataGrid.Rows()
方法是获取行列表的扩展方法:
public static IEnumerable<DataGridRow> Rows(this DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;
if (null != row) yield return row;
}
}
您的OnSelectedItemsCollectionChanged
方法不能是静态的。
将OnSelectedItemsChanged
方法的DependencyObject
参数转换为 ListView 类。 还要确保将处理程序与SelectedItems
属性的旧值分离。
private static void OnSelectedItemsChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listView = (ListView)d;
var oldCollection = (INotifyCollectionChanged)e.OldValue;
var newCollection = (INotifyCollectionChanged)e.NewValue;
if (oldCollection != null)
{
oldCollection.CollectionChanged -= listView.OnSelectedItemsCollectionChanged;
}
if (newCollection != null)
{
newCollection.CollectionChanged += listView.OnSelectedItemsCollectionChanged;
}
}
private void OnSelectedItemsCollectionChanged(
object sender, NotifyCollectionChangedEventArgs e)
{
foreach (var row in ObjectListDataGrid.Rows())
{
row.IsSelected = ObjectListDataGrid.SelectedItems.Contains(row.Item);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.