How to implement mvvm selecteditems in Communitytoolkit datagrid

55 views Asked by At

I'm using communitytoolkit datagrid and I'd like implent the selecteditems property in mvvm environment. I created a custom attachedproperty, but the selecteditems property of the datagrid, not inherit from INotifyCollectionChanged that I want to use for to reset the collection by code.

Thi is my attached property:

        public class SelectedItemsAttachedProperty
        {
           public static IList GetSelectedItems(DependencyObject obj)
           {
              return (IList)obj.GetValue(SelectedItemsProperty);
           }

           public static void SetSelectedItems(DependencyObject obj, IList value)
           {
              obj.SetValue(SelectedItemsProperty, value);
           }

           public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(SelectedItemsAttachedProperty), new PropertyMetadata(new ObservableCollection<object>(), SelectedItemsChanged));

           private static void SelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
           {
               if(d is DataGrid)
               {
                   DataGrid dg = d as DataGrid;
                   dg.SelectionChanged += (sender, e) =>
                   {
                       DataGrid it = sender as DataGrid;
                       foreach (var item in e.AddedItems)
                       {
                          it.SelectedItems.Add(item);
                       }

                       foreach (var item in e.RemovedItems)
                       {
                          it.SelectedItems.Remove(item);
                       }                    
                   };

                   var oc = dg.SelectedItems as INotifyCollectionChanged;

                   oc.CollectionChanged += (o, e) =>
                   {
                       if (e.Action == NotifyCollectionChangedAction.Reset)
                       {
                           dg.SelectedItems.Clear();
                       }
                   };
               }
           }
    }

Thanks

1

There are 1 answers

5
Andrew KeepCoding On BEST ANSWER

Instead of an attached property, you can create custom control:

public class DataGridEx : DataGrid
{
    public static readonly DependencyProperty SelectedItemsProperty =
        DependencyProperty.Register(
            nameof(SelectedItems),
            typeof(IList),
            typeof(DataGridEx),
            new PropertyMetadata(new ObservableCollection<object>()));

    public DataGridEx() : base()
    {
        this.SelectionChanged += DataGridEx_SelectionChanged;
    }

    public new IList SelectedItems
    {
        get { return (IList)GetValue(SelectedItemsProperty); }
        set { SetValue(SelectedItemsProperty, value); }
    }

    private void DataGridEx_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        foreach (object item in e.RemovedItems)
        {
            SelectedItems.Remove(item);
        }

        foreach (object item in e.AddedItems)
        {
            SelectedItems.Add(item);
        }
    }
}

UPDATE

You can get CollectionChanged events like this:

private void DataGridExControl_Loaded(object sender, RoutedEventArgs e)
{
    if (sender is not DataGridEx dataGridEx ||
        dataGridEx.SelectedItems is not INotifyCollectionChanged selectedItems)
    {
        return;
    }

    selectedItems.CollectionChanged += SelectedItems_CollectionChanged;
}

private void SelectedItems_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
}