gpt4 book ai didi

c# - 获取 DependencyProperties 源(绑定(bind)、const、...)并替换为包装器

转载 作者:太空狗 更新时间:2023-10-30 01:05:10 24 4
gpt4 key购买 nike

我试图通过数据绑定(bind)和附加属性将面板中的一整套控件设置为只读(例如,如果用户无权编辑)。(我知道将面板设置为禁用也会禁用其子项,但这太多了,因为它还会禁用超链接、列表等。)

基本上,属性更改事件处理程序迭代可视化树并找到所有 TextBox 子级,然后将它们的 IsReadOnly 属性设置为 true 或 false。这有效,但不包括 TextBox 已经具有 IsReadOnly 设置的情况 - const 或绑定(bind)。例如,如果 TextBox 应始终为只读,则附加属性不应将其更改为 true。此外,如果 TextBox 在某些情况下具有将 TextBox 限制为只读的绑定(bind),则附加属性不应盲目设置 true 或 false,而应组合设置,即如果附加属性和文本框绑定(bind)指示不只读,则它是可编辑的,否则它是只读的。

如何做到这一点?这将需要以某种方式获取当前的 IsReadOnly 设置(绑定(bind)、标记、常量值……)并将其替换为执行 AND 组合的包装器。如何获取依赖属性的当前设置/值源?我查看了以下内容,但看不出它如何解决我的问题:

        TextBox1.GetValue(TextBoxBase.IsReadOnlyProperty);
DependencyPropertyHelper.GetValueSource(TextBox1, TextBoxBase.IsReadOnlyProperty);
TextBox1.GetBindingExpression(TextBoxBase.IsReadOnlyProperty);

如有任何帮助,我们将不胜感激。

J.-

编辑:我正在寻找类似

的东西
(pseudo-code) 
TextBox1.IsReadOnly := OR(TextBox1.IsReadOnly, GlobalIsReadOnly)

如果设置了 GlobalIsReadOnly 标志,或者如果 TextBox1.IsReadOnly 值指示只读(无论是绑定(bind)、标记还是常量),现在将 TextBox1.IsReadOnly 设置为 true。

最佳答案

你可以使用 DependencyPropertyDescriptor Hook 您的 IsReadonly 属性更改处理程序(对于所有对象)。

(注意:添加到 DependencyPropertyDescriptor 的处理程序是 gcroot...请记住这一点以避免内存泄漏)

此 Hook 会尝试获取您的自定义附加属性,如果找到它并设置为“readonly forced”,如果它的值已更改,则将您的 IsReadOnly 属性重新设置为 false(但存储一个标志,可能在另一个附加的属性,以了解以后是否必须将其恢复为只读)。

但是,您的逻辑将覆盖 IsReadonly 上的任何绑定(bind)。但是相同的逻辑可以应用到绑定(bind)表达式(而不只是属性的值),使用 GetBindingExpression并存储/恢复在 IsReadonly 属性上设置的绑定(bind)表达式。

优点:一旦实现就不需要进一步的代码。

缺点: DependencyPropertyDescriptor.AddValueChanged“隐藏”了逻辑...因为没有任何线索表明此 IsReadonly 属性将绑定(bind)到您将编写的进一步 xaml 中的内容。

* 编辑:其他解决方案 *

使用多重绑定(bind),这应该可以工作(未测试)。但是,这有一些要求:

  • 绑定(bind)/值不得修改
  • 绑定(bind)必须在执行之前初始化

        var readonlyGlobalBinding = new Binding
    {
    Source = myRoot, // to fill
    Path = new PropertyPath(IsGlobalReadOnlyProperty)
    };
    var be = box.GetBindingExpression(TextBoxBase.IsReadOnlyProperty);
    if (be != null)
    {
    var mb = new MultiBinding();
    mb.Bindings.Add(be.ParentBinding);
    mb.Bindings.Add(readonlyGlobalBinding);
    mb.Converter = new OrConverter();
    box.SetBinding(TextBoxBase.IsReadOnlyProperty, mb);
    }else if(!box.IsReadOnly)
    box.SetBinding(TextBoxBase.IsReadOnlyProperty, readonlyGlobalBinding);

使用类

        class OrConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.OfType<bool>().Aggregate(false, (a, b) => a || b);
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}

关于c# - 获取 DependencyProperties 源(绑定(bind)、const、...)并替换为包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20048800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com