C# BindingSource不是';t侦听属性更改的所有项

C# BindingSource不是';t侦听属性更改的所有项,c#,winforms,datagridview,C#,Winforms,Datagridview,我知道我自己应该能解决这个问题,但我已经在桌子上敲了好几个小时了 我在DGV中有一个项目列表,希望DGV在属性更改时更新(本例中为一个属性)。下面是重现问题的完整示例。程序的输出为: Marking item 'One' as Missing Status changing Status changed has a listener Marking item 'Two' as Missing Status changing Marking item 'Three' as Missing Stat

我知道我自己应该能解决这个问题,但我已经在桌子上敲了好几个小时了

我在DGV中有一个项目列表,希望DGV在属性更改时更新(本例中为一个属性)。下面是重现问题的完整示例。程序的输出为:

Marking item 'One' as Missing
Status changing
Status changed has a listener
Marking item 'Two' as Missing
Status changing
Marking item 'Three' as Missing
Status changing
Marking item 'Four' as Missing
Status changing
您可以看到DGV上仅对第一个项目发生的更改。从该输出中可以看到,BindingSource正在侦听列表中第一个项目的属性更改,并将通知传递给DGV,但不发送任何其他通知

我错过了什么

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;

class Form1 : Form
{
    private enum ModuleStatus
    {
        Ok,
        Missing,
    }

    private sealed class ModuleInfo : INotifyPropertyChanged
    {
        public string Label { get; set; }
        private ModuleStatus _status;
        public ModuleStatus Status
        {
            get { return _status; }
            set
            {
                if (_status != value)
                {
                    Trace.WriteLine(String.Format("Status changing"));
                    _status = value;
                    OnPropertyChanged("Status");
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                Trace.WriteLine(String.Format("Status changed has a listener"));
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    private List<ModuleInfo> moduleList = new List<ModuleInfo>();
    private BindingSource moduleBinding;
    private Timer timer = new Timer { Enabled = true, Interval = 1000 };

    public Form1()
    {
        moduleBinding = new BindingSource(moduleList, null);
        Controls.Add(new DataGridView
        {
            Dock = DockStyle.Fill, AutoGenerateColumns = false, AllowUserToAddRows = false, RowHeadersVisible = false,
            Columns =
                {
                    new DataGridViewTextBoxColumn { HeaderText = "Label", DataPropertyName = "Label", AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, ReadOnly = true },
                    new DataGridViewTextBoxColumn { HeaderText = "Status", DataPropertyName = "Status", ReadOnly = true  },
                },
            DataSource = moduleBinding,
        });

        foreach (string label in new string[] { "One", "Two", "Three", "Four" })
            moduleBinding.Add(new ModuleInfo { Label = label, Status = ModuleStatus.Ok });

        timer.Tick += new EventHandler(timer_Tick);
    }

    int modifyIndex = 0;
    void timer_Tick(object sender, EventArgs e)
    {
        if (modifyIndex < moduleList.Count)
        {
            Trace.WriteLine(String.Format("Marking item '{0}' as Missing", moduleList[modifyIndex].Label));
            moduleList[modifyIndex].Status = ModuleStatus.Missing;
            modifyIndex++;
        }
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统诊断;
使用System.Windows.Forms;
类别表格1:表格
{
私有枚举模块状态
{
好啊
丢失的
}
私有密封类模块信息:INotifyPropertyChanged
{
公共字符串标签{get;set;}
私有模块状态;
公共地位
{
获取{return\u status;}
设置
{
如果(_status!=值)
{
Trace.WriteLine(String.Format(“状态更改”);
_状态=价值;
不动产变更(“状态”);
}
}
}
公共事件属性更改事件处理程序属性更改;
私有void OnPropertyChanged(字符串propertyName)
{
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
{
Trace.WriteLine(String.Format(“Status changed has a listener”);
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
私有列表模块列表=新列表();
私有绑定源模块绑定;
专用计时器=新计时器{Enabled=true,Interval=1000};
公共表格1()
{
moduleBinding=新的BindingSource(moduleList,null);
添加(新的DataGridView)
{
Dock=DockStyle.Fill,AutoGenerateColumns=false,AllowUserToAddress=false,RowHeadersVisible=false,
纵队=
{
新建DataGridViewTextBoxColumn{HeaderText=“Label”,DataPropertyName=“Label”,AutoSizeMode=DataGridViewAutoSizeColumnMode.Fill,ReadOnly=true},
新建DataGridViewTextBoxColumn{HeaderText=“Status”,DataPropertyName=“Status”,ReadOnly=true},
},
数据源=模块绑定,
});
foreach(新字符串[]{“一”、“二”、“三”、“四”}中的字符串标签)
moduleBind.Add(新的ModuleInfo{Label=Label,Status=ModuleStatus.Ok});
timer.Tick+=新事件处理程序(timer\u Tick);
}
int modifyIndex=0;
无效计时器勾号(对象发送方,事件参数e)
{
if(修改索引<模块列表计数)
{
Trace.WriteLine(String.Format(“将项{0}标记为丢失”,moduleList[modifyIndex].Label));
moduleList[modifyIndex]。状态=ModuleStatus.Missing;
modifyIndex++;
}
}
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(新Form1());
}
}

将模块列表更改为:

private BindingList<ModuleInfo> moduleList = new BindingList<ModuleInfo>();
private BindingList moduleList=new BindingList();

您可能会觉得这篇文章有用,也可能不会有用:

如果您先将项目2标记为缺失,会发生什么?@MalcolmO'Hare同样的事情,项目0是唯一更新的谢谢!我知道这很简单。很奇怪,它与
列表一起工作。