【发布时间】:2020-04-23 00:08:24
【问题描述】:
我正在开发一个应用程序,它使用分层对象结构并在 DataGridView 内的主 GUI 上显示这些对象的一些关键对象属性。当基础数据更改时,这些值必须更新。我考虑了几个选项:
- 将各个 DataGridView 单元格绑定到相关的对象属性。我知道这是不可能的,DGV 绑定就是全部或全部。
- 在网格单元格上动态定位文本框并绑定它们,但这看起来很混乱。
- 创建一个仅引用相关对象属性的中间列表/数组/集合,然后将该列表用作 DataGridView 的数据源。
- 响应 PropertyChanged 事件。复杂的是我有多个课程。顶级对象存在于 UI 范围内,并且有一个子对象,该子对象又可能有多个自己的子对象,依此类推。 UI 可以访问所有对象的属性,但不能访问它们的事件。
我一直在考虑将 PropertyChanged 事件从它发生在链上的任何级别传递,以便它可以在 UI 中进行处理。因此,在特定类中,我想在该类和任何子类中响应 OnPropertyChanged,并使引发的任何事件对父类可用。因此事件会沿着树向上流动到顶部。
我认为,我了解如何分别执行这两个步骤,参考以下内容:
Pass click event of child control to the parent control
但是,虽然我认为这两者可以结合起来,但我不太确定如何做到这一点。在 UI 中我得到了这个:
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 之间缺乏兼容性。不过,更根本的是,我不确定这种方法是否可行或最优。
如何最好地做到这一点?
【问题讨论】:
-
child 对象是否修改了主对象的属性? -- DataGridView 不能呈现嵌套对象值,所有对象都需要位于相同的层次结构级别。将您的对象绑定到 BindingSource(此类处理属性更改通知)并将 DGV 绑定到 BindingSource。或者使用 DataTable 来呈现数据:此类会自行引发通知更改(您可以将 DataTable 绑定到 BindingSource 以获得更多导航选项)。
-
正如我所说,我不认为数据绑定到 DGV 是显而易见的解决方案,因为其中的属性属于多个对象。您是否建议我使用包含来自不同对象的属性的中间列表并将其用作数据源?
-
DGV 中的数据只能以列和行的形式呈现,因此没有嵌套对象,您必须扁平化层次结构。你打算如何做以及你想在 DGV 中展示什么,你没有说。无论如何都需要一个表示层。如果您的表示层引发通知更改,则满足 UI 要求,BindingSource 可以处理您的类对象和 UI(在本例中为 DGV,但任何其他处理 DataBindings 的控件)之间的事务。
-
如我所说,DGV 显示了相关对象的主要属性(即用户最感兴趣的那些)。我意识到直接的 DGV 绑定不支持嵌套对象,因此不建议这样做。但是,我已经考虑并正在考虑使用仅包含要显示的那些属性的附加列表。据推测,只要它包含引用而不是值,它就会起作用。 UI 范围内的类级 List
可能会这样做... -
大量 cmets 没有错澄清您的问题。我可以建议您在问题中添加数据结构的详细信息/示例,并更详细地描述该结构如何在数据网格中显示。您想在网格中显示什么以及它在模型中的结构尚不清楚。