自定义TypeDescriptor和AddValueChange / OnValueChanged

时间:2019-02-06 21:10:53

标签: c# wpf customtypedescriptor

我正在探索使用自定义TypeDescriptors来拦截WPF控件上的数据绑定属性设置CLR属性的情况。由于种种原因,我需要找出哪个确切的控件正在设置一个值。

如果我使用INotifyPropertyChanged,我将获得在视图模型中订阅任何属性的所有不同控件,但并不是全部有用。因此,我认为我会沿着自定义的TypeDescriptor路径尝试尝试ProperyDescriptor.AddValueChangedPropertyDescriptor.OnValueChanged的方式。

我可以看到WPF按预期方式调用了ProperyDescriptor.AddValueChanged,但是我对ProperyDescriptor.OnValueChanged的调用似乎从未触发过对PropertyDescriptor.GetValue的调用以及UI中的更新。

使用我缺少的这些东西有一些陷阱吗?或者,还有其他方法可以确定谁在订阅CLR属性。我现在看到的替代方法是为整个shebang发出自定义代理,但我非常希望不必这样做。

编辑:仔细观察一下,我注意到我通过PropertyDescriptor.AddValueChanged获得的委托去了一些内部MS帮助器类,因此如果没有一些不可靠的反射-f,就无法使用它来获取源代码控制。我认为我必须使用具有依赖项属性的自定义代理。

1 个答案:

答案 0 :(得分:1)

有一种可能有用的替代方法。在绑定中,您可以将NotifyOnSourceUpdated设置为True,这将在WPF更新数据绑定到的CLR属性时引发控件的SourceUpdated事件。例如,在TextBox中,您可以编写:

<TextBox
    Text="{Binding MyText, NotifyOnSourceUpdated=True}"
    SourceUpdated="TextBox_OnSourceUpdated"
    />

在后面的代码中,您可以获得确切的控件(sender)和用于更新CLR属性的依赖项属性的名称:

private void TextBox_OnSourceUpdated(object sender, DataTransferEventArgs e)
{
    var control = (TextBox)sender;
    var propertyName = e.Property.Name;
}

使用这种方法,您需要知道该控件是TextBox,但是您可能可以对其进行更新以测试各种控件。实际上,这取决于您需要什么。