I'm trying to make some generic commands (move, delete rows) for WPF DataGrid. So far I have managed to write functions that work when I know DataGrid's ItemsSource is of type ObservableCollection<OrderRow>. But in future I will need to apply same commands to other types of lists so I thought that it should work on IList<> for maximal reusability. I tried table.ItemsSource is IList<object>
but that didn't work.
I can test if it's IList<>: table.ItemsSource.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)
but I still can't assign it to IList<> object. Surely I'm missing something simple...
For purpose of context, this bit shows what I'm currently doing:
public static readonly RoutedUICommand DeleteRows = new RoutedUICommand()
private void EditRow_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (e.OriginalSource is DataGrid table)
e.CanExecute = table.SelectedItems.Count > 0;
}
private void DeleteRows_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.OriginalSource is DataGrid table && table.ItemsSource is ObservableCollection<OrderRow> rows)
{
//Copy the selected items list contents so that it doesn't get cleared upon editing itemssource
var selected = new List<OrderRow>();
foreach (var item in table.SelectedItems)
if (item is OrderRow row) //This check is needed that item isn't a new item placeholder
selected.Add(row);
foreach (var row in selected)
rows.Remove(row);
}
}
<Window.CommandBindings>
<CommandBinding Command="local:CustomCommands.DeleteRows" CanExecute="EditRow_CanExecute" Executed="DeleteRows_Executed" />
</Window.CommandBindings>
Here's more reproducible example:
static void Main()
{
List<string> names = new List<string>() { "Alex", "Bart", "Charlie", "David", "Ellie" };
DeleteItems(names, new[] { "Bart", "David" });
foreach (string name in names)
Console.WriteLine(name);
Console.ReadLine();
}
//Takes IEnumerable as an argument because real use case is ItemsSource from DataGrid.
static void DeleteItems(IEnumerable<object> items, object[] selectedItems)
{
//This bit obviously doesn't work, IList<string> cannot be casted to IList<object>
if (items is IList<object> list)
{
foreach (var obj in selectedItems)
list.Remove(obj);
}
}