如何在双向绑定中从源传递更改?

时间:2011-09-19 15:49:11

标签: silverlight silverlight-4.0 mvvm

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

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

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

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

我原以为这会很简单,但我看不懂怎么做(标准的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}" />

2 个答案:

答案 0 :(得分:2)

您需要在metadata of your dependency property中添加Property Changed回调。

当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属性绑定到视图模型。当我单击视图中的文本时,视图和视图模型都会使用新文本“some value”进行更新。如果我更新viewmodel中的值(并引发属性更改事件),则在视图和控件中更新值,以便绑定仍然有效。

您的示例中必定还有其他一些缺失部分。

答案 1 :(得分:-1)

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