1

我知道我应该能够自己解决这个问题,但我已经把头撞在桌子上几个小时了。

我有一个 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());
    }
}
4

1 回答 1

2

将你的 moduleList 更改为:

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

您可能会也可能不会觉得这篇文章有帮助:BindingList vs List

于 2012-06-29T20:02:08.903 回答