c# - WPF 从具有双向绑定(bind)的 ViewModel 中选择 DataGrid 中的多个项目

标签 c# wpf mvvm datagrid

我正在尝试为 WPF DataGrid 中的选定项目创建双向绑定(bind).我希望能够从 ViewModel 中选择多个项目也来自实际的UserControl .我知道我不能直接设置选定的项目,因为这个属性是只读的。
我正在考虑绑定(bind)到 DependencyProperty并订阅 SelectionChanged DataGrid 的事件在后面的代码中。

<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;
    }
}
我使用 EventHandlerSelectionChanged DataGrid 的事件添加/删除集合中的项目。
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()方法是获取行列表的扩展方法:
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方法不能是静态的。
DependencyObject OnSelectedItemsChanged 的参数ListView 类的方法。还要确保将处理程序与 SelectedItems 的旧值分离。属性(property)。

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);
    }
}

关于c# - WPF 从具有双向绑定(bind)的 ViewModel 中选择 DataGrid 中的多个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64368174/

相关文章:

c# - 在WPF中从 View 更新EF模型

c# - DataGridView:确定 SQL 键值或关系?

c# - 从代码运行 SpecFlow 场景

wpf - 资源字典中的 DataTemplate 不继承自 app.xaml 样式?

c# - 动态调整 UserControl 大小的 WPF XAML 数据绑定(bind)

.net - MVVM 中的等待光标

c# - SqlBulkCopy.WriteToServer()不断获取“连接已关闭”

c# - "This BackgroundWorker states that it doesn' t 报告进度。”- 为什么?

c# - ComboBox SelectedItem 绑定(bind)

DataTemplate 中的 WPF 命令绑定(bind)