如何在UserControl中使用TwoWay绑定?

时间:2012-04-20 09:21:16

标签: wpf data-binding user-controls controltemplate

我有自己的UserControl,LabeledTextBoxLabel和a..well,TextBox的组合。此控件有两个属性:Caption将绑定到Label的标题,Value将绑定到Text的{​​{1}}

代码:

TextBox

XAML:

public class LabeledTextBox : Control
{
    static LabeledTextBox()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(LabeledTextBox), new FrameworkPropertyMetadata(typeof(LabeledTextBox)));
    }

    public string Caption
    {
        get { return (string)GetValue(CaptionProperty); }
        set { SetValue(CaptionProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Caption.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CaptionProperty =
        DependencyProperty.Register("Caption", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata(""));


    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(string), typeof(LabeledTextBox), new UIPropertyMetadata(""));


}

用法:

<Style TargetType="{x:Type local:LabeledTextBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:LabeledTextBox}">
                <Grid>
                    <Grid>

                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>

                    <Label Grid.Row="0" Content="{TemplateBinding Caption}" />
                    <TextBox  Name="Box" Margin="3,0,3,3" Grid.Row="1" Text="{Binding Value, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />

                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

最初我以为我在这里找到了答案:WPF TemplateBinding vs RelativeSource TemplatedParent

详细说明了<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode}" /> TemplateBinding之间的区别。我相应地更改了我的代码,但仍然觉得我错过了一步。 OneWay绑定确实有效,我的文本框绑定到Value属性,但更改不会注册。

如何让它发挥作用?

2 个答案:

答案 0 :(得分:7)

在此更改模式。

<uc:LabeledTextBox Caption="Code:" Value="{Binding ExpenseCode,Mode=TwoWay}"  /> 

它在我的最后工作

答案 1 :(得分:5)

以防任何人遇到此问题:

另一种方法(可能更优雅)是以某种方式声明usercontrol的依赖属性,以便它默认为双向绑定(例如,默认情况下框架TextBox)。

这可以通过以下方式实现(取自this Stackoverflow question的答案):

    public DependencyProperty SomeProperty =
        DependencyProperty.Register("Some", typeof(bool), typeof(Window1),
            new FrameworkPropertyMetadata(default(bool),
                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

此处的关键是使用FrameworkPropertyMetadata