3

我有一个简单的 Windows 窗体应用程序,它使用DataGridView绑定到BindingList<>我的自定义对象 (MCO)。

我还实现了针对 MCO 类型注册的自定义 TypeDescriptor 和自定义 PropertyDescriptor,目的是提供有关 DataGridView 的更多信息,而不是 MCO 的默认属性。自定义 TypeDescriptor 的 PropertyDescriptorCollection 返回来自父级的 PropertyDescriptor(MCO 的默认 PropertyDescriptor)和一个自定义 PropertyDescriptor。

一切都很好,当DataGridView绑定到 DataSource 时,显示的列对应于从自定义 TypeDescriptor 返回的列。

我还在 MCO 上实现了 INotifyPropertyChanged,以便在更改 MCO 属性时 datagridview 将刷新。然而,经过三天的互联网搜索并运行各种测试代码,我很难理解如何让自定义 PropertyDescriptor 也参与 INotifyPropertyChanged 事件。

例如说 MCO 看起来像这样

Public Class MyCustomObject : INotifyPropertyChanged
{
   public int Property1 { get; set;}

   //typical INotifyPropertyChanged implementation
}

然后我通过 TypeDescriptor.AddProvider() 添加一个自定义 PropertyDescriptor“VirtualProperty2”,它通过 PropertyDescriptor 的 getter 和 setter 映射到 Property1。

绑定时DatagridView,它将 Property1 和 VirtualProperty2 显示为两列,并且单元格的值与预期的一样。

如果我然后通过以下方式更改 Property1 的值 -

  1. 直接更新datagridview中的Property 1单元格
  2. 直接更新datagridview中的VirtualProperty2单元格
  3. 单击通过代码更新 MCO.Property1 实例的表单上的按钮

Property1 单元格将按预期刷新。但是 VirtualProperty2 只会在条件 2 中改变。

如果我在第 1 步或第 3 步之后单击 VirtualProperty2 的单元格,它将更新。(因为单击单元格必须触发调用 PropertyDescriptor 上的 getter 的事件)

当MCO中的Propery1触发它时,我需要VirtualProperty1的PropertyDescriptor来响应PropertyChanged事件,因为实际上VirtualPropery1被映射到Property1。

想法?

4

1 回答 1

0

在您的ICustomTypeDescriptor实现中,请确保您缓存了属性描述符。如果没有缓存,每次调用该方法时,您都会获得新的 - 未绑定的 - 实例。

public PropertyDescriptorCollection GetProperties()
{
    if (propertyCache == null)
    {
        propertyCache = new PropertyDescriptorCollection(someProperties.ToArray<PropertyDescriptor>());
    }

    return propertyCache;
}
于 2017-02-21T15:46:47.753 回答