簡體   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