2011-09-19 17 views
1

我创建了一个包含依赖项属性“文本”的自定义TextBox控件(但不是从TextBox派生的)。如何在TwoWay绑定中传递来自源的更改?

我已经添加了这个实例并将其绑定到我的视图模型上的一个属性使用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

所有DependencyProperty更新都通过SetValue在幕后触发绑定上的更改事件。你通常会添加一个set/get对到你的DP(这只是为你自己使用),它也调用GetValue/SetValue。你可以显示你的XAML和代码的控制和使用,因为它应该是微不足道的。设置你的文本属性不应该改变绑定。 –

+0

我正在设置一个Text属性,它自己调用了SetValue方法,但是这正在替换绑定 - 我将添加一些代码来演示它 –

回答

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

您的示例中必须存在一些其他缺失的部分。

+0

这个问题不是在绑定更改时更新我的​​自定义控件,而是更新自定义控件中的值通过绑定到视图模型。 –

+0

刚刚更新了我的答案,以解决您的评论。 – Bryant

+0

*点击桌面上的*你很对,缺少一些东西 - 在UserControl的XAML中,我将控件的DataContext设置为RelativeSource = Self,这意味着Text DP上的TwoWay绑定正试图绑定到控件本身而不是ViewModel上的一个属性,但并不完全确定行为是辉煌的,但我已经删除了DataContext,给定了控件的根x和Name,并使用ElementName绑定绑定了UserControl中的控件,现在所有的作品。在将来我必须更加注意输出窗口,这一切都很清楚! :) –

-1

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

+0

我没有使用实际的TextBox,我创建了一个自定义控件,我想支持TwoWay绑定。 –

相关问题