AvaloniaUI:UserControl中DirectProperty绑定同步问题求助
AvaloniaUI DirectProperty绑定不同步问题排查
问题描述
正在学习AvaloniaUI的DirectProperty机制,创建了TestUC用户控件并定义了Value类型的DirectProperty。在MainView和TestUC中各放置2个TextBox,全部绑定到MainViewModel的Greeting字段,期望4个TextBox内容同步,但TestUC内的TextBox无法与其他控件同步。
相关代码
MainView.axaml
<StackPanel> <Label Content="First in MainView"/> <TextBox Text="{Binding Greeting}" HorizontalAlignment="Stretch"/> <Label Content="Second in MainView"/> <TextBox Text="{Binding Greeting}" HorizontalAlignment="Stretch"/> <Label Content="UserControl"/> <uc:TestUC Value="{Binding Greeting}"/> </StackPanel>
TestUC.axaml
<StackPanel> <TextBox Text="{Binding Value,Mode=TwoWay}"/> <TextBox Text="{Binding Value,Mode=TwoWay}"/> </StackPanel>
TestUC.axaml.cs
public static readonly DirectProperty<TestUC, string> ValueProperty = AvaloniaProperty.RegisterDirect<TestUC, string>( nameof(Value), o => o.Value, (o, v) => o.Value = v, defaultBindingMode: BindingMode.TwoWay); private string _value; public string Value { get { return _value; } set { SetAndRaise(ValueProperty, ref _value, value); } }
问题原因
TestUC内部的TextBox绑定{Binding Value}默认会使用继承自父容器的DataContext(也就是MainViewModel),但MainViewModel中并没有Value属性,导致绑定失效,无法同步数据。而你期望的是绑定到TestUC控件自身的Value属性,而非父ViewModel。
解决方法
方法1:明确指定绑定源为TestUC控件(推荐)
修改TestUC.axaml,给UserControl设置x:Name,然后让TextBox绑定到该控件实例的Value属性:
<UserControl x:Class="TestAvalonia.TestUC" xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="SelfControl"> <StackPanel> <TextBox Text="{Binding Value, ElementName=SelfControl, Mode=TwoWay}"/> <TextBox Text="{Binding Value, ElementName=SelfControl, Mode=TwoWay}"/> </StackPanel> </UserControl>
也可以使用RelativeSource指定绑定到父级UserControl:
<TextBox Text="{Binding Value, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=TwoWay}"/>
方法2:设置TestUC的DataContext为自身(不推荐,会丢失父级上下文)
在TestUC的构造函数中把DataContext指向自身,这样内部绑定会默认找控件的属性:
public TestUC() { InitializeComponent(); DataContext = this; }
这种方式的弊端是TestUC将无法继承父容器的DataContext,如果后续需要绑定父ViewModel的其他属性会受限制。
总结
核心问题是绑定上下文的指向错误,只要让TestUC内部的TextBox明确绑定到控件自身的Value属性,就能实现4个TextBox的同步更新。
内容的提问来源于stack exchange,提问作者Prodromos
相关产品推荐
相关产品推荐

