我编写了具有可绑定属性的控件.此控件还具有修改该属性值的方法:
public class MyControl : ContentView // WPF: inherited from UserControl
{
// Xamarin:
public static readonly BindableProperty MyValueProperty = ...
// WPF:
// public static readonly DependencyProperty MyValueProperty = ...
public int MyValue
{
get { return (int) GetValue(MyValueProperty); }
set { SetValue(MyValueProperty, value); }
}
public void Reset()
{
MyValue = 0;
}
}
我在普通的XAML页面中使用该控件,并通过绑定更新MyValue:
<local:MyControl x:Name="TheControl"
MyValue="{Binding MyValueSource, Mode=OneWay}" />
绑定最初将更改从MyValueSource传播到MyValue.但是,一旦调用一次Reset()方法,绑定将被0覆盖,并且不再提取对MyValueSource的更新.
我想MyValue的任何直接分配都打算替换OneWay绑定.使用TwoWay绑定,更改仅传播回MyValueSource,并且绑定仍然有效.
如果Reset()在视图模型中,则可以执行以下操作:
public void Reset()
{
// TheControl.MyValue = 0; // Bad practice, destroys the binding
MyValueSource = 0; // Good practice, preserves the binding
}
我不想在每个VM中都实现复位逻辑(比此简化示例中的复位逻辑更复杂),因此它位于视图/控件中.
所以我想知道-您可以从控件的后面代码中分配可绑定属性的值,并且仍然保留可能的OneWay绑定吗?我知道这意味着VM无法获得更改后的值;如果控件也更新属性,则绑定OneWay可能不正确;您应该先使用TwoWay绑定.
但是,如果有人在XAML中说出OneWay,那么我宁愿让它表现得如此真实,而不是实施某些“ OneWay,直到您调用Reset()”行为.
旁注:我在Xamarin中工作,但我猜WPF的行为是相同的. 解决方法: 取出并充实from @Clemens’ comment:
WPF
您可以在DependencyObject (即控件)上使用SetCurrentValue 方法来更改DependencyProperty 的当前有效值.与SetValue 不同,使用SetCurrentValue时,该属性的任何触发器,数据绑定和样式均保持不变.
public void Reset()
{
// this.SetValue(MyValueProperty, 0); // Replaces the binding
this.SetCurrentValue(MyValueProperty, 0); // Keeps the binding
}
请记住,如果定义了OneWay绑定,则不会向视图模型通知更改的值,并且VM的MyValueSource属性的任何更改将再次覆盖控件的值(如果正确实现了该属性).
Xamarin
当前没有不替换附加的OneWay绑定就分配BindableProperty 值的正确方法. BindableObject (控件的基类)没有可与WPF的SetCurrentValue相比的任何方法,并且SetValue 将始终替换绑定.
但是,如果将绑定更改为BindingMode.TwoWay,则内部值更改将传播回视图模型.无论如何,您可能都应该这样做,以使控件和VM保持同步.
public void Reset()
{
// Replaces any OneWay bindings
// Updates MyValueSource for TwoWay bindings
this.SetValue(MyValueProperty, 0);
}
来源:https://www./content-4-523201.html
|