【问题标题】:Custom TypeDescriptor and AddValueChange/OnValueChanged自定义 TypeDescriptor 和 AddValueChange/OnValueChanged
【发布时间】:2019-06-30 22:28:24
【问题描述】:

我正在探索使用自定义 TypeDescriptors 在 WPF 控件上的数据绑定属性设置 CLR 属性时进行拦截。由于某些原因,我需要弄清楚哪个确切的控件正在设置一个值。

如果我使用INotifyPropertyChanged,我将获得订阅视图模型中任何属性的所有不同控件,但并没有那么有用。所以我想我会沿着自定义的TypeDescriptor 路径尝试ProperyDescriptor.AddValueChangedPropertyDescriptor.OnValueChanged 的方式。

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

使用这些我遗漏的东西有什么问题吗?或者还有其他方法可以确定谁订阅了 CLR 属性。我现在看到的替代方案是为整个 shebang 发出一个自定义代理,但我非常不想这样做。

编辑:仔细观察,我注意到我通过PropertyDescriptor.AddValueChanged 获得的代表转到了一些内部 MS 助手类,因此如果没有一些不可靠的反射,就无法使用它来获得源代码控制。我想我必须使用具有依赖属性的自定义代理。

【问题讨论】:

    标签: c# wpf customtypedescriptor


    【解决方案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,但您可以更新它以测试不同类型的控件。这取决于你需要这个,真的。

    【讨论】:

    • 谢谢,这可能很有用。我的目标是避免在视图/视图模型中进行欺骗,并拥有一个透明的基础视图模型。但这似乎并不像我希望的那样容易......
    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多