繁体   English   中英

WPF 从具有双向绑定的 ViewModel 中选择 DataGrid 中的多个项目

[英]WPF Select multiple items in DataGrid from ViewModel with twoway binding

我正在尝试创建到 WPF DataGrid所选项目的双向绑定。 我希望能够从ViewModel和实际的UserControl选择多个项目。 我知道我无法直接设置所选项目,因为此属性是只读的。

我正在考虑绑定到DependencyProperty并在后面的代码中订阅DataGridSelectionChanged事件。

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

我使用EventHandlerDataGridSelectionChanged事件来添加/删除集合中的项目。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM