简体   繁体   English

如何将 TextBox 的 Text 双向数据绑定到 Dependency 属性

[英]How to Two-way databind a TextBox's Text to a Dependency property

I'm trying to two-way data bind a TextBox's Text property to the parent window's dependency property.我正在尝试双向数据将 TextBox 的 Text 属性绑定到父窗口的依赖属性。

I've trimmed down the problem to just a few lines in a test project to try to get the binding to work, and have been googling around for days.我已经在测试项目中将问题缩减为几行,以尝试让绑定工作,并且已经搜索了好几天。

From the Xaml file:从 Xaml 文件:

<StackPanel>
    <TextBox Text="{Binding A, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Mode=TwoWay}" Margin="5"/>
    <TextBox Text="{Binding B, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}, Mode=TwoWay}" Margin="5"/>
    <Button Content="Random" Click="Button_Click" Margin="5"/>
</StackPanel>

and from the CS file:并从 CS 文件:

public partial class MainWindow : Window
{
    public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(double), typeof(MainWindow));
    public double A
    {
        get { return (double)GetValue(AProperty); }
        set
        {
            SetValue(AProperty, value);
            SetValue(BProperty, value);
        }
    }

    public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(double), typeof(MainWindow));
    public double B
    {
        get { return (double)GetValue(BProperty); }
        set
        {
            SetValue(AProperty, value);
            SetValue(BProperty, value);
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        A = 0d;
        B = 1d;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        A = new Random().Next();
    }
}

When the window starts, both TextBox's show "1" (as expected because of the constructor).当窗口启动时,两个 TextBox 都显示“1”(由于构造函数,正如预期的那样)。 Clicking the button causes both TextBox's to update to a random number (also as expected).单击该按钮会导致两个 TextBox 都更新为随机数(也符合预期)。

But changing the text in either TextBox does not update the bound dependency property, hence it won't update the other TextBox.但是更改任一 TextBox 中的文本不会更新绑定的依赖项属性,因此不会更新其他 TextBox。

There aren't any error messages during these operations.在这些操作期间没有任何错误消息。

If you want A to set B and vice versa, you should use callbacks.如果你想让A设置B ,反之亦然,你应该使用回调。 The setter of the CLR wrapper should only call SetValue of the dependency property itself and don't do anything else, eg: CLR 包装器的 setter 应该调用依赖属性本身的SetValue而不要做任何其他事情,例如:

public static readonly DependencyProperty AProperty = DependencyProperty.Register("A", typeof(double), typeof(MainWindow),
    new PropertyMetadata(new PropertyChangedCallback(OnAChanged)));

public double A
{
    get { return (double)GetValue(AProperty); }
    set { SetValue(AProperty, value); }
}

private static void OnAChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    MainWindow window = (MainWindow)d;
    window.B = window.A;
}

public static readonly DependencyProperty BProperty = DependencyProperty.Register("B", typeof(double), typeof(MainWindow));
public double B
{
    get { return (double)GetValue(BProperty); }
    set { SetValue(BProperty, value); }
}

Also note that you should set the UpdateSourceTrigger property of the bindings to PropertyChanged if you want the source property to be set for each keystroke.另请注意,如果您希望为每次击键设置源属性,则应将绑定的UpdateSourceTrigger属性设置为PropertyChanged By default, they will be set when the TextBox loses focus.默认情况下,它们将在TextBox失去焦点时设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM