【问题标题】:How to control two-way binding initial update direction如何控制双向绑定初始更新方向
【发布时间】:2016-04-14 22:24:08
【问题描述】:

我时不时会遇到需要在属性上设置双向绑定的情况,在这种情况下,最好在设置绑定时初始更新将在目标到源方向而不是源方向上执行-达到目标。也就是说,当设置绑定时,源属性值会更新,以便它反映目标属性值,而目标属性值保持不变。

这种情况可能吗?如果是,如何实现?

当然有几种解决方法,例如缓存目标属性值、设置绑定然后恢复缓存的值,但我感兴趣的是直接答案而不是解决方法。

示例

假设我们有一个TextBox,其中Text 属性设置为"foo"。另外,我们有一个视图模型,其Name 属性(string 类型)设置为null。现在我想要实现的是将Text 属性绑定到Name 属性,同时保留"foo" 值。这里重要的是避免将Text 设置为null,然后再设置回"foo"(无论出于何种原因,例如因为清除TextBox 会导致其他控件也被清除)。

【问题讨论】:

    标签: c# .net wpf data-binding dependency-properties


    【解决方案1】:

    我认为最好的选择是在模型类中设置一个默认值。这就是视图模型的目的。

    【讨论】:

    • 问题是我想保留 current 值,而不是 default 值。此外,此解决方案假定使用 MVVM 模式,而且该模型是“我的”,这也可能不是真的,例如绑定的源显式设置为其他一些 WPF 控件。
    • 你提到你有一个视图模型,所以我假设你使用 MVVM 不正确?
    • 您的视图模型应该设置所有默认值,并且不应依赖 WPF,因为您可以在通用应用程序等其他应用程序中使用它。我不明白您为什么不想遵循这种方法?请给我一个真实的例子,你想在哪里设置这样的默认值。
    • 确实我提到了一个视图模型,但这只是一个例子。我有一般技术问题,我不想将其限制为特定的设计模式。我知道对于问题的每个实例都可能存在解决方案,但我的兴趣是知道是否存在完成问题中描述的场景的“通用”方式。再举一个例子,假设我正在开发一个控件库,最终用户在其中提供绑定,然后我需要在布局相关属性上设置该绑定以保存布局。我不知道是否存在 VM...
    【解决方案2】:

    那么最佳实践是 1) 从控件中读取现有值(显然 Xaml 不应该具有数据绑定)。 2) 在“Load”事件中,控件需要通过调用“SetBinding”来创建和建立数据绑定。 3) 最后获取控件的绑定表达式,并使用 1) 中的值更新源。

    所有代码都应该在“View”代码中实现,而不是在“ViewModel”中。

    例如)这段代码 sn-p 未经测试,但来自我在球场上的脑袋。

    private void Loaded(object sender, RoutedEventArg arg)
    {
    ...
       var text = textBox.Text;
       var binding = new Binding();
       ... binding property here
    
       textBox.SetBinding(TextBox.TextProperty, binding);
       textBox.Text = text;
    
       var expression = BindingExpression.GetBindingExpression(textBox, TextBox.TextProperty);
       expression.UpdateSource();
    }
    

    【讨论】:

    • 感谢您的关注。我知道这种技术(我在问题中提到它作为一种解决方法),但这不是我想要的。此外,我认为不需要在 Loaded 事件上执行此操作(它在任何给定时间都可以正常工作),并且我认为检索绑定表达式并调用 UpdateSource() 是多余的(源将被更新设置Text 属性时自动)。
    【解决方案3】:

    如何创建一个可用于任何 UIElement 的附加属性?这应该解决普遍性要求。

    <TextBlock Text="foo" 
               GlobalAttachedProperty:Value="{Binding Path=A_ValueFromVM_OR_SomeWhereElse}"
               GlobalAttachedProperty:Property="Text"/>
    

    Value 属性只包含一个回调,用于在发生更改时设置绑定。您可以添加一些花哨的例程,只执行一次。

    那么Property 只是获取实际属性以进行绑定的一种方式。还有一些其他的方法可以做到这一点,但这是更直接的方法。

    【讨论】:

      猜你喜欢
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-07
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多