【问题标题】:How do I update an ObservableCollection item's property from change in a WPF DataGrid?如何根据 WPF DataGrid 中的更改更新 ObservableCollection 项属性?
【发布时间】:2012-04-16 13:50:05
【问题描述】:

我有一个 WPF DataGrid,它的数据源是 ObservableCollection。大致如下设置:

public class ItemDataCollection : ObservableCollection<ItemData>
{
}

public class ItemData : INotifyPropertyChanged
{
    private bool _selected = true;
    public bool Selected 
    { 
        get
        {
            return _selected;
        }
        set
        {
            if (value != _selected)
            {
                _selected = value;
                NotifyPropertyChanged("Selected");
            }
        }
    }
    }


    _itemDataCol = new ItemDataCollection();
        <... fill the _itemDataCol with data here ...>
    dataGrid1.ItemsSource = _itemDataCol;

当集合更新时,dataGrid1.Items.Refresh() 会很好地更新 dataGrid1。但是,当我通过选中或取消选中与该属性对应的行中的复选框来修改行的“选定”属性时,集合中的项目不会更新。我查看了 ObservableCollection 的 CollectionChanged 事件,但这似乎没有被触发。我需要什么接线才能让 dataGrid1 更新集合。

更新

我所做的只是将 ItemSource 属性设置为 ObservableCollection 并让列自动生成。我已经改为直接绑定,并发现了问题的更多细节。当我简单地选中该框时 - 不会触发任何通知。但是,如果我在选中该框后点击,则集合会更新。这是绑定:

<DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay}" Header="Selected"></DataGridCheckBoxColumn>

所以我想问题是我如何在选中或取消选中该框后必须点击才能获得更新?

更新 #2 (我无法回答,因为我的代表还不够高) 好的 - 我想我有解决方案。如果我在绑定中包含“UpdateSourceTrigger=PropertyChanged”,一切似乎都可以正常工作。

<DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Header="Selected"></DataGridCheckBoxColumn>

如果有任何我可能遗漏的负面影响,请离开 cmets。感谢您的帮助!

【问题讨论】:

    标签: c# wpf binding wpfdatagrid observablecollection


    【解决方案1】:

    答案是我需要将 UpdateSourceTrigger 设置为 PropertyChanged(请参阅 Blam 的回复)。似乎不需要指定双向绑定。这是工作代码中的标记:

    <DataGridCheckBoxColumn Binding="{Binding Path=Selected,
         UpdateSourceTrigger=PropertyChanged}" 
         Header="Selected"></DataGridCheckBoxColumn>
    

    【讨论】:

    • 我在搞乱这个网站——在上面发帖还是新手。当我注意到它未选中您的时,我重新接受了,但没有接受。这不是我的意图 - 你得到了接受的答案。
    • 这很奇怪,因为它表明你今天既接受了又不接受了。答案显示一个复选标记,但我没有得到信用。请尝试单击复选标记。如果我没有得到信用,那就没问题了。很好,你成功了。
    • 嗯。我尝试不接受并再次接受。它确实将您的帖子显示为已接受的答案 - 至少在我不同机器上的浏览器中。我很抱歉 - 你是第一个发帖的,应该是你的功劳。这就是我玩没有损坏的东西所得到的......
    • 您是否尝试接受您的回答?我敢打赌,这就是杀死我的答案的原因。
    【解决方案2】:

    ObservableCollection 不监听其项目的 INotifyPropertyChanged 事件;请改用BindingList

    换句话说,[an ObservableCollection] 仅在添加或删除项目时通知,而不是 当其项目的值发生变化时,即使这些项目实现 INotifyPropertyChanged。相比之下,BindingList 确实监听 INotifyPropertyChanged,因此,如果其项目被修改,则 更改将反映在网格中。结果分组、排序、 和统计功能将被更新。

    http://xceed.com/CS/blogs/dontpanic/archive/2009/04/01/i-notify-we-notify-we-all-wait-no-we-don-t.aspx

    【讨论】:

      【解决方案3】:

      CollectionChanged 用于插入和删除。 NotifyPropertyChanged 用于更新项目。在发布的代码中,您实际上并没有实现 INotifyPropertyChanged。

         public event PropertyChangedEventHandler PropertyChanged;
          private void NotifyPropertyChanged(String info)
          {
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs(info));
              }
          }
      

      而且我认为绑定到返回 _itemDataCol 的公共属性会更干净

      否则 celopez3 的 TwoWay 答案

      【讨论】:

      • 对不起 - 我省略了 NotifyPropertyChanged 的​​实现以保持帖子简短。它在我的实际代码中正确实现。
      • 它被调用了吗? set 是否被调用?请尝试绑定到公共属性。如果一切都失败了,请尝试绕过您 ItemDataCollection 并直接提供 ObservableCollection (用于测试)。
      • 我尝试了以下方法: 选择是公开的。问题是,如果我在选中或取消选中该框后点击 ,则 ObservableCollection 会更新。但是,仅选中该框并不足以触发更新。
      • 您需要将UpdateSourceTrigger设置为PropertyChanged msdn.microsoft.com/en-us/library/…
      【解决方案4】:

      我不确定您在帖子中是否提供了足够的信息,但我会尽力提供帮助。我的第一个问题是:您如何绑定到复选框?必须注意,如果您希望复选框影响可观察集合,您必须在项目上设置“双向”绑定,默认情况下绑定是“单向”并且不会自动更改集合中的项目.另一种处理方法是在复选框上添加一个事件,单击该事件后,您将手动更改可观察集合中的值。

      【讨论】:

      • 我所做的只是将 ItemSource 属性设置为 ObservableCollection 并让列自动生成。我已经改为直接绑定,并发现了问题的更多细节。当我简单地选中该框时 - 不会触发任何通知。但是,如果我在选中该框后按 ,则集合会更新。这是绑定: 有什么想法吗?
      猜你喜欢
      • 2012-10-26
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 2017-11-19
      相关资源
      最近更新 更多