【问题标题】:Allow only OneWayToSource binding mode仅允许 OneWayToSource 绑定模式
【发布时间】:2016-06-08 15:48:34
【问题描述】:

我有EntitiesUserControl 负责EntitiesCount 依赖属性:

public static readonly DependencyProperty EntitiesCountProperty = DependencyProperty.Register(
    nameof(EntitiesCount),
    typeof(int),
    typeof(EntitiesUserControl),
    new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

public int EntitiesCount
{
    get { return (int)this.GetValue(EntitiesCountProperty); }
    set { this.SetValue(EntitiesCountProperty, value); }
}

另一个(主)控件包括EntitiesUserControl并通过绑定读取它的属性:

<controls:EntitiesUserControl EntitiesCount="{Binding CountOfEntities, Mode=OneWayToSource}" />

CountOfEntities视图模型中的属性只是存储和处理计数值的变化:

private int countOfEntities;
public int CountOfEntities
{
    protected get { return this.countOfEntities; }
    set
    {
        this.countOfEntities = value;
        // Custom logic with new value...
    }
}

我需要EntitiesUserControlEntitiesCount 属性为只读(主控件不能更改它,只需读取),它之所以这样工作,是因为Mode=OneWayToSource 明确声明。但是如果声明TwoWay 模式或不显式声明模式,则EntitiesCount 可以从外部重写(至少在绑定初始化之后,因为它发生在分配默认依赖属性值之后)。

由于绑定限制(在此answer 中进行了最佳描述),我无法执行“合法”只读依赖属性,因此我需要防止使用OneWayToSource 以外的模式进行绑定。最好在 FrameworkPropertyMetadataOptions 枚举中有一些 OnlyOneWayToSource 标志,例如 BindsTwoWayByDefault 值...

有什么建议可以实现吗?

【问题讨论】:

  • 我不确定使用Mode=OneWayToSource 有什么问题。唯一的问题是您必须输入它还是什么?抱歉,我不太了解这里的问题。我将分享一种仅实现 OneWayToSource 绑定的 hacky 方法,但不确定这是否是您所需要的。
  • @SzabolcsDézsi 问题不在于我必须输入,问题恰恰相反——我可能不会输入,什么也没有会告诉我,我将以不应该使用的方式使用财产。打个比方——如果你编写的代码为只读属性赋值,你就无法编译程序。
  • @Sam FWIW 我同意你的观点,也希望看到一个优雅的解决方案。但是 XAML 或 WPF 似乎没有任何内容支持您所指的安全理念:(

标签: c# wpf xaml data-binding dependency-properties


【解决方案1】:

这是一个“有点”hacky,但您可以创建一个Binding 派生类并使用它来代替Binding

[MarkupExtensionReturnType(typeof(OneWayToSourceBinding))]
public class OneWayToSourceBinding : Binding
{
    public OneWayToSourceBinding()
    {
        Mode = BindingMode.OneWayToSource;
    }

    public OneWayToSourceBinding(string path) : base(path)
    {
        Mode = BindingMode.OneWayToSource;
    }

    public new BindingMode Mode
    {
        get { return BindingMode.OneWayToSource; }
        set
        {
            if (value == BindingMode.OneWayToSource)
            {
                base.Mode = value;
            }
        }
    }
}

在 XAML 中:

<controls:EntitiesUserControl EntitiesCount="{local:OneWayToSourceBinding CountOfEntities}" />

命名空间映射local 可能适合您。

OneWayToSourceBindingMode 设置为OneWayToSource,并防止将其设置为其他任何值。

【讨论】:

  • 谢谢,例如,这很有趣,至少我用这种方式使用了较新的绑定...这不是我所需要的,但它有点相对:就像您的自定义绑定防止使用任何'OneWayToSource' 以外的模式,我需要依赖属性来防止绑定到自己的自定义绑定以外的任何绑定,或与“OneWayToSource”以外的模式的任何标准绑定。
猜你喜欢
  • 2011-12-30
  • 2014-12-04
  • 1970-01-01
  • 2018-08-07
  • 2014-08-27
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多