如何在 TwoWay 绑定中传递来自源的更改?

发布于 2024-12-05 11:45:08 字数 1018 浏览 1 评论 0原文

我创建了一个自定义 TextBox 控件(但不是从 TextBox 派生),其中包含依赖项属性“Text”。

我添加了一个实例,并使用 TwoWay 绑定将其绑定到我的视图模型上的属性。

在我的自定义 TextBox 控件中,如何更新 Text 属性,以便将更改传播到视图模型上的属性?

如果我在自定义控件上设置“文本”属性,则会替换绑定,使视图模型上的属性保留为空。

我本以为这很简单,但我不知道如何做到这一点(标准 TextBox 控件必须做到这一点!)

干杯

编辑:

自定义控件:

public class SampleCustomControl : CustomControl
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(SampleCustomControl), new PropertyMetadata(null));

    public void Update()
    {
        // This replaces my binding, I want it to pass the new value 
        // through to the "SomeProperty" two way binding.
        Text = "some value";
    }

}

用法:

<Controls:SampleCustomControl Text="{Binding SomeProperty, Mode=TwoWay}" />

I have created a custom TextBox control (but not derived from TextBox) that contains a Dependency Property "Text".

I have added an instance of this and bound it to a property on my view model using a TwoWay binding.

From within my custom TextBox control, how do I update the Text property in such a way that the change is propagated to the property on the view model?

If I set the "Text" property on my custom control, that replaces the binding leaving the property on the view model as null.

I would have thought this would be simple but I can't see how to do it (the standard TextBox control must do it!)

Cheers

Edit:

Custom Control:

public class SampleCustomControl : CustomControl
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(SampleCustomControl), new PropertyMetadata(null));

    public void Update()
    {
        // This replaces my binding, I want it to pass the new value 
        // through to the "SomeProperty" two way binding.
        Text = "some value";
    }

}

Usage:

<Controls:SampleCustomControl Text="{Binding SomeProperty, Mode=TwoWay}" />

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难理解 2024-12-12 11:45:08

您需要在 依赖属性的元数据

当 Text 属性更改(从任一侧)时,将触发此回调。您可以使用从中传入的值来更新您为显示文本而构建的自定义 UI。

更新:
回应你关于这件事的评论。由于您的示例代码太模糊而无法测试,因此这是我用来测试您的问题的代码。

public class TestControl : ContentControl
{
    private TextBlock _tb;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _tb = new TextBlock();
        _tb.Text = Text;
        this.Content = _tb;
        _tb.MouseLeftButtonDown += new MouseButtonEventHandler(_tb_MouseLeftButtonDown);
    }

    void _tb_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Update();
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(TestControl), new PropertyMetadata(string.Empty, OnTextChanged));

    public void Update()
    {
        // This replaces my binding, I want it to pass the new value 
        // through to the "SomeProperty" two way binding.
        Text = "some value";
    }

    public static void OnTextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        ((TestControl)sender).UpdateText((string)e.NewValue);
    }

    protected void UpdateText(string text)
    {
        if (_tb != null) _tb.Text = text;
    }
}

然后,我使用双向绑定将控件上的 Text 属性绑定到视图模型。当我单击视图中的文本时,视图和视图模型都会使用新文本“某些值”进行更新。如果我更新视图模型中的值(并引发属性更改事件),则视图和控件中的值会更新,因此绑定仍然有效。

您的示例中肯定还缺少其他一些部分。

You need to add a Property Changed callback in the metadata of your dependency property.

This callback will be fired when the Text property changes (from either side). You can use the value passed in from this to update your custom UI that you've built to display the text.

Update:
Responding to your comment about what this is about. Since your example code is too vague to test, here is what I used to test your problem.

public class TestControl : ContentControl
{
    private TextBlock _tb;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _tb = new TextBlock();
        _tb.Text = Text;
        this.Content = _tb;
        _tb.MouseLeftButtonDown += new MouseButtonEventHandler(_tb_MouseLeftButtonDown);
    }

    void _tb_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Update();
    }

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(TestControl), new PropertyMetadata(string.Empty, OnTextChanged));

    public void Update()
    {
        // This replaces my binding, I want it to pass the new value 
        // through to the "SomeProperty" two way binding.
        Text = "some value";
    }

    public static void OnTextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        ((TestControl)sender).UpdateText((string)e.NewValue);
    }

    protected void UpdateText(string text)
    {
        if (_tb != null) _tb.Text = text;
    }
}

I then bound the Text property on my control to the view model using a two way binding. When I click the text in the view both the view and the viewmodel get updated with the new text "some value". If I update the value in the viewmodel (and raise the property changed event) the value gets updated in the view and the control so the binding is still valid.

There must be some other missing pieces in your example.

清风不识月 2024-12-12 11:45:08

只要您的绑定属性设置为 TwoWay 并且您已公开 getter 和 setter,您在 TextBox 中输入的文本就会发送到 ViewModel。然而,我相信当您失去控制焦点时,实际的发送就会发生。

As long as your binding property is set to TwoWay and you have exposed the getter and the setter, than the text you enter in the TextBox is sent to the ViewModel. I believe the actual send occurs when you lose focus of that control however, i believe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文