【问题标题】:Collection was modified when trying to remove selected items of datagrid尝试删除数据网格的选定项目时修改了集合
【发布时间】:2015-06-22 21:09:06
【问题描述】:

通过关注this answer,我的编码方式几乎相同。以下是我的部分代码。

XAML 绑定:

<cst:CustomDataGrid x:Name="grdItems"   ItemsSource="{Binding myItems, IsAsync=True}"   SelectedItemsList="{Binding SelectedItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"                            

视图模型:

   Protected Overrides Sub DeleteCurrent()
        Dim msg As New UserMessage()
        If SelectedItems IsNot Nothing Then
            For Each SelectedItem In SelectedItems
                  myItems.Remove(SelectedItem)
            Next

            RaisePropertyChanged("Items")

        End If

    End Sub


Private m_myItems As ObservableCollection(Of item)
    Public Property myItems() As ObservableCollection(Of item)
        Get
            Return m_myItems
        End Get
        Set(value As ObservableCollection(Of item))
            m_myItems = value
        End Set
    End Property


    Private m_SelectedItem As IList = New List(Of item)()
    Public Property SelectedItems() As IList
        Get
            Return m_SelectedItem
        End Get
        Set(value As IList)
            m_SelectedItem = value
            '   RaisePropertyChanged("SelectedItems")
        End Set
    End Property

选择效果很好。但是当我循环删除选定的每个项目时,我收到“集合已修改。枚举操作可能无法执行。”的异常。例如,我选择 3 行并按下删除键盘按钮,当我观察到我的 SelectedItems 对象时,计数为 3,但在使用 myItems.Remove(SelectedItem) 执行该行之后,计数下降到 1。为什么会发生这种情况,我无法弄清楚,因为我不是在修改 SelectedItems,而是在修改 myItems。

PS; customdatagrid 的代码与上面的原始帖子完全相同。这就是为什么我没有在这里添加它。

【问题讨论】:

    标签: wpf vb.net mvvm wpfdatagrid


    【解决方案1】:

    “我无法弄清楚,因为我不是在修改 SelectedItems,而是在修改 myItems”

    您正在从 myItems 中删除项目,该项目用作数据网格的 ItemsSource。自动从 ItemsSource 中删除项目,然后从 SelectedItems 中删除它,这种行为非常合理(当项目不再在数据网格中时,您不能保持选中状态)。

    这就是错误的原因。枚举时不能让集合发生变化。

    实现此目的的一种可能方法是将选定的项目复制到临时集合,例如临时数组。然后枚举数组而不是原始集合:

    Dim copyOfSelectedItems(SelectedItems.Count-1) As Object
    SelectedItems.CopyTo(copyOfSelectedItems,0)
    For Each SelectedItem In copyOfSelectedItems
          myItems.Remove(SelectedItem)
    Next
    

    【讨论】:

      【解决方案2】:

      在执行 foreach 循环时只需将选定项复制到新集合,例如使用 ToArray linq 扩展方法:

      For Each SelectedItem In SelectedItems.ToArray()
          myItems.Remove(SelectedItem)
       Next
      

      【讨论】:

      • ToArray 不适用于 Collections.Ilist,但我想出了如何使用 toarray。所以首先需要铸造。对于每个 SelectedItem 在 SelectedItems.Cast(Of item).ToArray() myItems.Remove(SelectedItem) Next
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 2015-10-29
      • 2023-03-20
      相关资源
      最近更新 更多