我正在开发一个使用分层对象结构的应用程序,并在DataGridView的主GUI上显示这些对象的一些关键对象属性。当基础数据更改时,这些值必须更新。我考虑了一些选择:
我一直在考虑从链上发生的任何级别传递PropertyChanged事件,以便可以在UI中进行处理。因此,在一个特定的类中,我想响应该类中以及所有子类中的OnPropertyChanged,并使引发的所有事件对父类可用。这样事件就会从树上流到顶部。
我认为,我参考以下内容了解如何分别执行两个步骤:
Pass click event of child control to the parent control
但是,尽管我认为两者可以结合使用,但是我不确定如何做到这一点。在用户界面中,我得到了这个:
project.PropertyChanged += new PropertyChangedEventHandler(ProjectPropertyChanged);
private void ProjectPropertyChanged(object sender, PropertyChangedEventArgs e) {
MessageBox.Show("In main UI. Project property changed!");
}
然后向下一层,我得到了这样的东西:
public class Project : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Project() {
childObject.PropertyChanged += new PropertyChangedEventHandler(ProjectPropertyChanged);
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
ProjectPropertyChanged(sender, e); // this doesn't work due to different parameters
}
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
// Event available to parent class
}
}
这样的想法是,每个类都将其自己的OnPropertyChanged()事件传递给其PropertyChanged()方法,并响应其子级的OnPropertyChanged()事件,并将所有事件公开给父类。
如果要这样做,理想情况下,我想保留有关更改哪个属性的知识,以便做出相应的响应。
最直接的问题是由于参数不同,ProjectPropertyChanged和OnPropertyChanged之间缺乏兼容性。不过,从更根本上来说,我不确定此方法是否可行或最佳。
如何最好地做到这一点?
答案 0 :(得分:0)
要回答我自己的问题:
我尝试使用DataTable(根据this question.)对中间绑定源执行此操作,但未成功。问题是我无法创建对数据对象的引用。 DataTable似乎包含值。
所以我最终使用了我更确定的方法,但是使用起来却不太优雅,这是上面我的问题中的选项2。我将标签放置在需要绑定数据值的位置,然后绑定到这些标签。这行得通。
经过简化,并假装我们的物体是动物,我的解决方法是:
Label[,] dashboardLabels = new Label[3,14];
private void Form1_Shown(object sender, EventArgs e)
{
CreateLabels(); // create and position labels (no binding yet)
}
public void CreateLabels(int cols = 3, int rows = 14)
{
for (int col = 0; col < cols; col++)
{
for (int row = 0; row < rows; row++)
{
// Create label...
Label l = new Label();
l.Text = "N/A";
l.ForeColor = Color.Red
dashboardLabels[col, row] = l;
this.Controls.Add(l);
// Position label over DGV cell...
Point dgvCell = dataGridView1.GetCellDisplayRectangle(col + 2, rowNumbersLabel[row], false).Location;
Point dgvGrid = dataGridView1.Location;
l.Left = dgvGrid.X + dgvCell.X;
l.Top = dgvGrid.Y + dgvCell.Y;
}
}
}
private void UpdateLabels(List<Dog> dogs)
{
for (int i = 0; i < dogs; i++)
{
if (!dashboardLabels[i, 0].Visible) dashboardLabels[i, 0].Visible = true;
if (dogs[i].IsSetUp) BindLabel(dashboardLabels[i, 0], dogs[i],"Name");
}
}
private void BindLabel(Label l, Dog dog, string observation)
{
Binding b = new Binding("Text", dog, observation);
l.DataBindings.Add(b);
l.ForeColor = Color.Green;
}
}
然后在创建对象时,我叫UpdateLabels()
。如果未初始化,标签此时将以红色显示“ N / A”。如果初始化,标签将变为绿色,并绑定到对象的名称,因此它将从该点开始自动更新。
我做了很多搜索,发现的信息表明DataGridView不支持复杂的数据绑定,即,一个DGV几乎是一个类,或者根本不支持。我也找不到能做到这一点的类似网格的控件。