【问题标题】:Issue with removing item from ObservableCollection, I am doing something wrong从 ObservableCollection 中删除项目的问题,我做错了什么
【发布时间】:2017-03-03 18:43:54
【问题描述】:

我有一个 DataGrid,其中包含有关产品的信息,例如名称和价格, 可以通过按下 DEL 键(删除大小写)在 DataGrid 中添加或删除项目。

我使用 ObservableCollection 作为 DataGrid 源,它看起来像这样:

ObservableCollection<ProductTemporary> result = ProductsTempController.Instance.SelectAll();

我的窗口上还有一个按钮,它一直在更新我的产品价格总和,添加项目时总和增加,删除项目时总和减少等等......

在我的情况下,我在从我的收藏中删除项目时遇到问题,好吧,正如我所说的,我是通过按 DEL 键来完成的,所以这是我的代码:

if (e.Key == Key.Delete)
{
    if (dataGridProducts.SelectedItem != null)
    {
        ProductTemporary tempItem = (ProductTemporary)dataGridProducts.SelectedItem;
        ProductTemporaryController.Instance.Delete(tempItem.Id);

        UpdateTotalAmount();
    }
}


public void UpdateTotalAmount()
{
    double sum = 0;
    foreach (var item in result)
    {
        sum += Convert.ToDouble(item.TotalAmount);
    }
    btnTotal.Content = string.Format("{0:0.00}", sum) + " " + EUR;
}

可以看到,首先我要从数据库中删除项目,ObservableCollection 会小心地将其从 UI 中删除,但在这种情况下我仍然遇到问题:

假设datagrid上有2个项目,当用户按下del时,项目将从数据库中删除,但方法UpdateTotalAmount();之后会被调用,在我的集合中会有两个项目,我会看到不正确的总和..

所以我可能没有在正确的地方调用这个 UpdateTotalAmount 或类似的东西,

我也想过这个解决方案:

在删除项目的存储过程中,我可以从数据库中发回总项目的总和,所以在这种情况下,我不需要循环任何集合来做那样的事情,但我认为这不是一个好习惯?

谢谢各位, 干杯

【问题讨论】:

  • FWIW 这种东西在使用 MVVM 时往往更容易
  • @BradleyDotNET FWIW?
  • 物有所值
  • @Roxy'Pro,从源对象而不是控件中删除所选项目。即使更新控件,可观察集合也应该引发属性更改
  • @Roxy'Pro,显然选择会改变,你正在删除一个项目

标签: c# wpf collections datagrid


【解决方案1】:

除了在事件处理程序中调用 DeleteUpdateTotalAmount 方法,您还可以处理 ObservableCollectionCollectionChanged 事件,并在项目从集合中删除时从数据库中删除它:

ObservableCollection<ProductTemporary> result = new ObservableCollection<ProductTemporary>();//ProductsTempController.Instance.SelectAll();
result.CollectionChanged += (ss, ee) => 
{
    if(ee.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove 
        && ee.OldItems !=null && ee.OldItems.Count > 0)
    {
        ProductTemporary removedItem = ee.OldItems[0] as ProductTemporary;
        ProductTemporaryController.Instance.Delete(removedItem.Id);
        UpdateTotalAmount();
    }
};

那么您根本不需要任何PreviewKeyDown 事件处理程序。

【讨论】:

  • @mm8 这是一个很好的答案!但你能否逐行解释得更详细,它工作得很好,但我想知道到底发生了什么!
  • 还有一件事,通过这种方式你做到了我不能例如问用户他是否确定他会删除该项目?例如 MessageBox.Show("您确定要删除所选项目");在那种情况下,我必须再次寻找 PreviewKeyDown 事件处理程序?
  • 您可以在事件处理程序中显示 MessageBox,但如果用户确认,仍会删除 CollectionChanged 事件中的项目。 CollectionChanged 是一个在集合中添加或删除项目时触发的事件。
  • 如果我只想在用户按下 Del Key 时删除 PreviewKeyDown 事件处理程序上的项目,我是否应该将您发布的代码移动到 Del Key Down 事件处理程序中?或者是什么 ?我的意思是我想控制何时更改集合(仅在 Key.Down Delete 上)?
  • 如果您只想在按下 DELETE 键时执行某些操作,处理 PreviewKeyDown 事件听起来是个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 2019-04-20
  • 2013-10-20
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多