如何从WPF DataGrid中更改ObservableCollection项目的属性?

4

我有一个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。但是当我通过选中或取消选中与该属性对应的行中的复选框来修改一行的“Selected”属性时,集合中的项目并未得到更新。我查看了ObeservableCollection的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>

如果我忽略了任何负面影响,请留下评论。感谢您的帮助!

4个回答

4

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

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

我认为将绑定到一个公共属性,其中您返回_itemDataCol更加清晰。
否则,celopez3的TwoWay答案可能会导致问题。

抱歉 - 我为了让帖子更简短而省略了NotifyPropertyChanged的实现。在我的实际代码中,它已经正确地实现了。 - K J
它被调用了吗?set 被调用了吗?请尝试绑定到公共属性。如果所有这些都失败了,请尝试绕过您的 ItemDataCollection 并直接提供一个 ObservableCollection<ItemData>(用于测试)。 - paparazzo
我尝试了以下代码:其中Selected是公共的。问题在于,如果我在勾选或取消勾选框后按下<enter>键,ObservableCollection将被更新。但仅仅勾选框并不能触发更新。 - K J
1
你需要将UpdateSourceTrigger设置为PropertyChanged。http://msdn.microsoft.com/zh-cn/library/system.windows.data.binding.updatesourcetrigger.aspx - paparazzo

3
一个 ObservableCollection 不会监听其项的 INotifyPropertyChanged 事件;使用 BindingList 代替。
换句话说,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

0
答案是我需要将UpdateSourceTrigger设置为PropertyChanged(见Blam的回答)。似乎不需要指定双向绑定。以下是工作代码中的标记:
<DataGridCheckBoxColumn Binding="{Binding Path=Selected,
     UpdateSourceTrigger=PropertyChanged}" 
     Header="Selected"></DataGridCheckBoxColumn>

我在玩弄这个网站 - 对于发布还很新。当我注意到它取消了你的选择时,我重新接受了它,但它没有生效。这不是我的意图 - 你赢得了被接受的答案。 - K J
这很奇怪,因为它显示你今天既接受又未接受。答案显示了一个勾号,但我没有得到积分。请尝试单击勾号。如果我没有得到积分,那也没关系。很好,你让它工作了。 - paparazzo
嗯,我尝试了取消接受和重新接受。在我的不同机器上的浏览器中,它确实显示您的帖子为被接受的答案。我很抱歉 - 您是第一个发布帖子的人,应该归功于您。这就是我玩弄本来没有问题的东西所得到的结果... - K J
你试过接受你的答案吗?我敢打赌那就是导致我的答案被删除的原因。 - paparazzo

0

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


我所做的只是将ItemSource属性设置为ObservableCollection并让列自动生成。现在我已经改为直接绑定,并找到了更多问题的详细信息。当我简单地勾选框时,不会触发任何通知。但是如果我在勾选框后按<enter>,则集合将被更新。这是绑定:<DataGridCheckBoxColumn Binding="{Binding Path=Selected, Mode=TwoWay}" Header="Selected"></DataGridCheckBoxColumn>有什么想法吗? - K J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接