C# 在WPF数据网格中为ItemSource创建代理,这可能吗?

C# 在WPF数据网格中为ItemSource创建代理,这可能吗?,c#,wpf,datagrid,C#,Wpf,Datagrid,在我目前正在处理的项目中,我没有可与datagrid绑定的普通CLR对象。通常,我会使用ObservableCollection,但现在我不能使用,而是必须使用自定义对象(其行为类似于DataTable,但具有自定义逻辑) 我的问题是:如何创建一个代理/适配器对象,将datagrid单元格中项上的每个绑定操作“转换”为自定义逻辑对象 记住: 我的对象不是集合,所以我没有真正的项目 虚拟项的“列”可能会更改 在应用程序的某个地方,我可能会更改该对象中的一个值,并且datagrid必须反映更改

在我目前正在处理的项目中,我没有可与datagrid绑定的普通CLR对象。通常,我会使用ObservableCollection
,但现在我不能使用,而是必须使用自定义对象(其行为类似于DataTable,但具有自定义逻辑)

我的问题是:如何创建一个代理/适配器对象,将datagrid单元格中项上的每个绑定操作“转换”为自定义逻辑对象

记住:

  • 我的对象不是集合,所以我没有真正的项目
  • 虚拟项的“列”可能会更改
  • 在应用程序的某个地方,我可能会更改该对象中的一个值,并且datagrid必须反映更改
现在,我们正在从自定义对象重新创建一个DataTable,以使其DataView显示在datagrid中,我们截获带有事件的编辑命令(很难看),然后在每次更改单元格值时从头重新加载所有内容

我搜索了一些关于如何实现这一点的提示,但我发现的是:

  • IITempProperties接口(可能对动态列感兴趣,但我没有集合)
  • DataSourceProvider类(它似乎是ItemsSource的包装器,但我看不到必须在Data属性中返回什么)
  • INotifyPropertyChanged接口(告诉属性已更改,但我没有项或至少项没有属性)
  • ICustomTypeDescriptor接口(可以,但一旦我用GetProperties()返回属性,datagrid将如何尝试修改不存在的属性?)

正如您所看到的,选择一种实现好的代理的方法是令人困惑的。

是.NET4.0。您可以通过继承DynamicObject(.net4.0)轻松创建代理,DynamicObject的动态属性将在xaml中绑定。如果代理数据表,则必须在其代理上实现
INotifyCollectionChanged
,如果代理项目,则需要在其代理上实现
INotifyPropertyChanged

我建议创建一种ViewModel作为模型之间的适配器(不是集合但被视为一个集合的神秘对象)和您的视图(DataGrid)。在搜索模型视图ViewModel时,您将找到此模式的各种示例。
然后您可以自己定义属性,只需在属性上实现一些合适的get/set方法,即可将ViewModel更改传递到原始模型,反之亦然(如果需要).

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

我认为您在实现时没有注意到应该通知项的更改。我也看到了这个,但它不是我试图绑定的集合,它是一个自定义对象,具有自己的编辑、绑定、添加和通知mecanism。INotifyCollectionChanged与ICollection没有关联,它只允许订阅者(也称为data grid想知道您何时添加、删除或移动了行显示的数据。是的,我可以使用.net 4。在将数据发送到ItemsSource之前是否需要强制转换为dynamic?我更喜欢使用尽可能少的代码隐藏,我担心我无法在XAML中键入dynamic。XAML实际上使用运行时绑定,因此无需担心强制转换。我一直在DataContext中使用ExpandoObjects(它已经支持INotifyPropertyChanged)。维护ExpandoObjects以及我的对象的列表会影响应用程序的性能吗?我希望在这样的接口中看到一个方法解决方案:公共接口IDataGridBindingMagic{object GetColumns();对象GetRowCount();对象GetCellValue(行、列);无效SetCellValue(行、列、值);事件ACellHasChanged();}然后,我将很容易地提出背后的逻辑…但这似乎并不存在。我不会使用Expandos,我给出了一个不需要强制转换的示例,我建议使用一个自定义代理,它继承并实现适当的接口