我知道我应该能够自己解决这个问题,但我已经把头撞在桌子上几个小时了。
我有一个 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());
}
}