【问题标题】:Making a proxy for ItemSource in a WPF Datagrid, is this possible?在 WPF Datagrid 中为 ItemSource 制作代理,这可能吗?
【发布时间】:2011-03-02 20:06:47
【问题描述】:

在我目前正在进行的项目中,我没有普通的 CLR 对象来绑定我的数据网格。通常,我会使用 ObservableCollection<MyObject>,但现在我不能,而是必须使用自定义对象(其行为类似于 DataTable,但具有自定义逻辑)。

我的问题是:如何制作一个代理/适配器对象,它将我的数据网格单元格中项目的每个绑定操作“转换”为我的自定义逻辑对象?

记住:

  • 我的对象不是集合,所以我没有真正的项目。
  • 虚拟物品的“列”可能会改变。
  • 在应用程序的某个地方,我可能会更改该对象中的一个值,并且数据网格必须反映更改

现在我们正在从自定义对象重新创建一个 DataTable 以让他的 DataView 显示在数据网格中,我们拦截带有事件的编辑命令(这很丑陋),然后每次更改单元格值时从头开始重新加载所有内容。

我搜索了有关如何完成此操作的提示,但我发现的是:

  • IItemProperties 接口(拥有动态列可能会很有趣,但我没有集合)
  • DataSourceProvider 类(它似乎是 ItemsSource 的包装器,但我没有看到必须在 Data 属性中返回什么)
  • INotifyPropertyChanged 接口(告诉某个属性已更改,但我没有项目或至少项目没有属性)
  • ICustomTypeDescriptor 接口(好的,但是一旦我使用 GetProperties() 返回了属性,数据网格将如何尝试修改不存在的属性?)

如您所见,选择一种实现良好代理的方式令人困惑。

【问题讨论】:

  • 我想你错过了INotifyCollectionChanged,当你实现它时应该通知项目的变化。
  • 我也看到了那个,但它不是我要绑定的集合,它是一个自定义对象,具有他自己的编辑、绑定、添加和通知机制。
  • INotifyCollectionChanged 与 ICollection 没有关联,它只是让订阅者(又名)数据网格知道您何时添加、删除或移动了行显示的数据。

标签: c# wpf datagrid


【解决方案1】:

最后我找到了一个解决方案,我在this web site 中使用了第二种方法:并创建了一个从 IBindingList 和 ITypedList 继承的对象来假冒该项目是一个列表,我还在每个假行上使用了 ICustomTypeDescriptor 并调用了主表对象。

【讨论】:

    【解决方案2】:

    我建议创建一种 ViewModel 作为模型(不是集合但被视为一个集合的神秘对象)和视图(DataGrid)之间的适配器。在搜索 Model-View-ViewModel 时,您会发现此模式的各种示例。 然后你可以自己定义属性,你只需要在你的属性上实现一些合适的get/set-methods,将ViewModel-changes转移到你原来的Model,反之亦然(如果需要的话)。

    【讨论】:

      【解决方案3】:

      .net 4.0 是否可用。您可以通过从 DynamicObject(仅限 .net 4.0)继承其动态属性将绑定到 xaml 来轻松创建代理。如果您代理您的 DataTable,您必须在其代理上实现 INotifyCollectionChanged,如果您代理您的项目,您需要在其代理上实现 INotifyPropertyChanged

      【讨论】:

      • 是的,我可以使用 .net 4。在将其发送到我的 ItemsSource 之前,我是否需要强制转换为动态?我宁愿使用尽可能少的代码隐藏,我担心我无法在 XAML 中输入动态。
      • XAML 实际上使用运行时绑定,所以不用担心不需要强制转换。我一直在 DataContext 中使用 ExpandoObjects(它已经支持 INotifyPropertyChanged)。
      • 维护 ExpandoObject 列表以及我的对象是否会损害应用程序的性能?我希望在这样的接口中看到一个方法的解决方案: public interface IDataGridBindingMagic { object GetColumns();对象 GetRowCount();对象GetCellValue(行,列);无效SetCellValue(行,列,值);事件 ACellHasChanged(); } 然后我会很容易地使背后的逻辑......但这似乎不存在。
      • 我不会使用 Expandos,我举了一个不需要强制转换的例子,我建议使用继承自 DynamicObject 并实现适当接口的自定义代理
      猜你喜欢
      • 2018-12-09
      • 2014-04-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 2011-10-10
      • 2013-03-18
      • 2012-05-06
      • 2012-11-21
      相关资源
      最近更新 更多