简体   繁体   中英

WPF: Binding Property to an object in Style

I have this style:

<Style x:Key="{x:Type TextBox}" TargetType="TextBox">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True" CornerRadius="0,10,10,0" Padding="5,0,10,0" MinWidth="0" VerticalAlignment="Stretch">
                        <Grid VerticalAlignment="Center">
                            <Label x:Name="label" Content="{Binding LContent}" HorizontalAlignment="Left" VerticalAlignment="Stretch" Foreground="Gray" Padding="0,0,5,0" Margin="0" BorderBrush="#FF2C2C2C" BorderThickness="0,0,1,0"/>
                            <Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
                                <ScrollViewer x:Name="PART_ContentHost" Focusable="False" Template="{DynamicResource ComboBoxScrollViewerControlTemplate}" Margin="30,1,0,0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" />
                            </Grid>
                        </Grid>
                    </Border>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="CaretBrush" Value="#FF646464"/>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="False">
                <Setter Property="CaretBrush" Value="#FF323232"/>
            </Trigger>
        </Style.Triggers>
    </Style>

and in behind code, I wrote this function as new property for Label object to binding LContent value to label object:

public string LabelContent
    {
        get { return (string)GetValue(LContent); }
        set { SetValue(LContent, value); }
    }
    public static readonly DependencyProperty LContent =
        DependencyProperty.Register("LabelContent", typeof(string), typeof(CustomizedTextBox), new PropertyMetadata("Label"));

but label content doesn't change. can you help me?

You've approached template binding in the same way as you would a normal control, and this is wrong. Think of it this way: it is a total and utter waste of time to define a template if you are going to explicitly bind to a specific property. A template is supposed to be reused across multiple instances of a control, and they can't all be binding to that one property, could they?

Instead what you need to do is use:

{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Name}

or its shorted version:

{TemplateBinding Name}

This tells the binding subsystem to use the parent control (the one you are templating) as a source for the binding.

This cheat sheet might be a valuable reference for you. The previous SO question What is the template binding vs binding? also has a nice simple example of this.

First of all I'm not sure what x:Key="{x:Type TextBox}" does, but make sure the data context is propely set. Like if you're using it in a window

You can do

<Window.DataContext>
    <local:CustomizedTextBox></local:CustomizedTextBox>
</Window.DataContext>

Though it's not a good practice.

And also I noticed that you've Registered the Property Name as LabelContent and you are using LContent in the Binding. Changing it to LabelContent can help.

 <Label x:Name="label" Content="{Binding LabelContent}" >

You've set you're TargetType to be TextBox and even if your custom control is derived from TextBox it will not apply to it, you should directly Specify your custom controls class name that is CustomTextBox .

To make things clear, I would say that If you've ax:Key attribute in you're style, if will not automatically get applied to all the targetType element. Then you have to explicitly specify the style for each control.

And to get you exited, I have made this work. If you want I will later post what I have done. But now I am in a hurry.

Hope it, helps.

To set the label content directly from the text box text, we need to set the content of the label to the Text property of the Text box

<Label x:Name="label"  "{Binding Text, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}"

To read the set value of the label which can be done directly using the property with INotifyPropertyChanged or Dependency property in your case where MyMainWindow is the my usercontrol window name

<TextBox Grid.Row="0" x:Name="CustomizedTextBox" Text="{Binding ElementName=MyMainWindow, Path=LabelContent }"

In Code base we have DP defined as below

public static readonly DependencyProperty LContentProperty =
        DependencyProperty.Register("LabelContent", typeof(string), typeof(MainWindow));

    public string LabelContent
    {
        get { return (string)GetValue(LContentProperty); }
        set { SetValue(LContentProperty, value); }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM