绑定到可观测集合的 DataGrid 多选在视图模型中修改可观测集合时不稳定



我正在构建一个 WPF C# 应用程序,该应用程序将多个DataGrids绑定到包含对象的各自ObservableCollections

我将重点介绍与ConduitsObservableCollection绑定以保持简单DataGrid

DataGrids设置为多选SelectionMode="Extended"DataGrids中的数据也通过Canvas和图形元素在二维视图中表示。

这个想法是用户可以选择2D或DataGrids中的对象,作为单个项目或多个项目/行,并且DataGrid行或2D中的对象将被突出显示。

这产生了一些不稳定的结果。太多了,无法列出,所以我将专注于删除项目。当DataGridViewModels尚未初始化时,我可以毫无问题地删除 2D 中的对象。初始化后,我在 2D 中删除时出现以下错误。

`System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'`

对象在 2D 中删除,如下所示:

foreach (object _conduit in SelectedConduitList)
{
if (_conduit is Conduit conduit)
{
Conduits.Remove(conduit);
}
}

关联的DataGrid绑定到对象,以及选定的对象,如下所示:

<custom:ConduitDataGrid
ItemsSource="{Binding Path=NetworkMain.Conduits}" 
SelectionMode="Extended"
SelectedItemsList="{Binding NetworkMain.SelectedConduitList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">

以下是导管DataGridsObservableCollection和所选导管的列表

public ObservableCollection<Conduit> Conduits { get; set; } = new();
private IList _selectedConduitList = new ArrayList();
public IList SelectedConduitList
{
get { return _selectedConduitList; }
set
{
_selectedConduitList = value;
//changes the IsSelected property of all objects in the ObserbservableCollection to false 
DeselectAll();
//changes the IsSelected property of all objects in the ObserbservableCollection to true if the object exists in the SelectedConduitList
SelectConduits();
NotifyOfPropertyChange(nameof(SelectedConduitList));
}
}

为了使DataGrids将多个选定的行绑定到SelectedConduitList,使用了自定义datagrid,如下所示:

public class ConduitDataGrid : DataGrid
{
public ConduitDataGrid()
{
this.SelectionChanged += CustomDataGrid_SelectionChanged;
}
void CustomDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.SelectedItemsList = this.SelectedItems;
}
#region SelectedItemsList
public IList SelectedItemsList
{
get { return (IList)GetValue(SelectedItemsListProperty); }
set 
{ 
SetValue(SelectedItemsListProperty, value); 

}
}
public static readonly DependencyProperty SelectedItemsListProperty = 
DependencyProperty.Register(nameof(SelectedItemsList), typeof(IList), typeof(ConduitDataGrid), new PropertyMetadata(null));
#endregion
}

有谁知道为什么我不能从我的 2D 布局ViewModel中修改(例如删除)SelectedConduitList中的对象,而不会在初始化DataGrid ViewModels后抛出错误?

当数据网格视图模型尚未初始化时,我可以毫无问题地删除 2D 中的对象。初始化后,我在 2D 中删除时出现以下错误。

从源附加到的集合中删除会导致从选定元素的集合中删除,在该集合上有一个 foreach 循环。 不允许在 foreach 源运行时更改它。
这是一个常见问题,最简单的解决方案是创建列表的副本,然后循环访问它。

foreach (Conduit conduit in SelectedConduitList.OfType<Conduit>().ToList())
{
Conduits.Remove(conduit);
}

异常消息意味着在使用foreach循环枚举项时,无法从IEnumerable中删除该项。

一般的解决方案是将foreach循环替换为for循环,并向后循环访问集合:

for (int i = SelectedConduitList.Count - 1; i >= 0; i--)
{
Conduit conduit = SelectedConduitList[i] as Conduit;
if (conduit != null)
Conduits.Remove(conduit);
}

有关详细信息,请参阅此博客文章。

最新更新