How to use TwoWay binding from within a UserControl?

扶醉桌前 提交于 2020-01-03 09:44:09

问题


I have my own UserControl, a LabeledTextBox which is the combination of a Label and a..well, TextBox. This Control has two properties: Caption which will be bound to the caption of the Label, and Value which will be bound to the Text of the TextBox.

Code:

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(""));


}

XAML:

<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>

Usage:

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

Initially I thought I had found my answer here: WPF TemplateBinding vs RelativeSource TemplatedParent

That details the difference between TemplateBinding and RelativeSource TemplatedParent. I've changed my code accordingly, but it still feels like I'm missing a step. The OneWay binding does work, my textbox is bound to the Value property, but changes do not register.

How do I get this to work?


回答1:


Change the mode here.

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

it worked at my end




回答2:


Just in case anybody has this problem:

Another approach (maybe more elegant) would be to declare the dependency property of the usercontrol in a way so that it defaults to two way binding (e.g. as the framework TextBox does by default).

This can be achieved as follows (taken from the answer of this Stackoverflow question):

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

The key here is using FrameworkPropertyMetadata.



来源:https://stackoverflow.com/questions/10243445/how-to-use-twoway-binding-from-within-a-usercontrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!