依赖属性绑定和更新到自定义控件--它会更新,但显然不是双向的
本文关键字:更新 绑定 属性 自定义控件 依赖 | 更新日期: 2023-09-27 18:19:28
ViewModel:
public class MyViewModel : INotifyPropertyChanged
{
public string MyText { ... }
}
XAML:
<my:MySpecialTextBox Text="{Binding MyText}" />
自定义控制:
public class MySpecialTextBox : TextBox
{
static MySpecialTextBox()
{
TextProperty.OverrideMetadata(typeof(MySpecialTextBox),
new FrameworkPropertyMetadata
{
BindsTwoWayByDefault = true,
DefaultValue = string.empty,
PropertyChangedCallback = OnTextPropertyChanged
});
}
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as MySpecialTextBox;
if (control != null)
{
control.Text = SomeAdjustedValue((string)e.NewValue);
}
}
}
<小时>问题是,尽管自定义控件中的DependencyProperty调整正确,但它不会更新ViewModel。我意识到,由于SomeAdjustedValue的命名,这个似乎是一个强制值回调,但强制也不会更改ViewModel值。如果它是OnTextPropertyChanged回调的触发器,那么我似乎无法更新ViewModel中的值。。。我做了一个调试跟踪,它没有使用新值第二次通过ViewModel。不知道该怎么办才能解决这个问题。
小时>在FrameworkPropertyMetadata中,可以使用不同的构造函数。将一个与FrameworkPropertyMetadataOptions参数一起使用。FrameworkPropertyMetadataOptions.BindsTwoWayByDefault选项默认情况下将启用双向绑定,否则仅为单向绑定。
编辑:你这么做了,我生病的时候不应该再回答问题了。
首先是免责声明-这闻起来像是应该存在于ViewModel中的逻辑,而不是UI绑定中的逻辑。
也就是说,如果你打算这样做,我认为你需要首先检查"调整后的值"是否与已经提供的值不同(以避免无限循环),然后使用DependencyProperty.SetValue来设置控件的依赖属性的值,而不仅仅是设置它的Text属性。
TextBox.Text
是一个绑定,您将用OnTextPropertyChanged
中的字符串值替换该绑定,因此该属性不再绑定到您的数据源。
我认为您需要获得TextBox.Text
上的绑定并更新源代码,但我不建议这样做,因为您将把业务逻辑层与UI层混合在一起。
如果你只想显示一些自定义格式,我会在转换器中进行,这样它就不会实际更改数据源的值。如果您想更改实际的数据源值,我会使用ViewModel的PropertyChanged
事件
你试过这个吗?
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as MySpecialTextBox;
if (control != null)
{
control.SetCurrentValue(TextBox.TextProperty, SomeAdjustedValue((string)e.NewValue));
}
}
SetCurrentValue()方法确保保留绑定,其中如果使用Text属性setter,则在后台调用一个简单的SetValue()将删除任何绑定。