BindingSource没有监听属性更改的所有项目

时间:2012-06-29 19:40:37

标签: 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
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());
    }
}

1 个答案:

答案 0 :(得分:2)

将moduleList更改为:

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

您可能会或可能不会发现这篇文章有用:BindingList vs List