WPF:将属性绑定到Style中的对象

时间:2015-10-03 18:34:34

标签: c# wpf

我有这种风格:

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

在后面的代码中,我将此函数编写为Label对象的新属性,以将LContent值绑定到label对象:

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

但标签内容没有变化。 你能救我吗?

3 个答案:

答案 0 :(得分:2)

您以与普通控件相同的方式接近模板绑定,这是错误的。可以这样想:如果您要明确绑定到特定属性,那么定义模板是完全浪费时间的。模板应该在控件的多个实例中重用,并且它们不能全部绑定到那个属性,是吗?

相反,您需要做的是使用:

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

或其缩短版本:

{TemplateBinding Name}

这告诉绑定子系统使用父控件(您正在模板化的控件)作为绑定源。

This cheat sheet可能对您有价值的参考。之前的SO问题What is the template binding vs binding?也有一个很好的简单示例。

答案 1 :(得分:0)

首先,我不确定x:Key="{x:Type TextBox}"做了什么,但要确保数据上下文正确设置。就像你在窗口

中使用它一样

你可以做到

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

虽然这不是一个好习惯。

我还注意到您已将属性名称注册为 LabelContent ,并且您在Binding中使用了LContent。将其更改为LabelContent可能有所帮助。

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

您已将 TargetType 设置为TextBox,即使您的自定义控件是从TextBox派生的,它也不适用于它,您应该直接指定您的自定义控件类名<强> CustomTextBox 即可。

为了清楚说明,我会说如果你的样式中有x:Key属性,那么if将不会自动应用于所有 targetType 元素。然后,您必须明确指定每个控件的样式。

为了让你退出,我已经完成了这项工作。如果你愿意,我会稍后发布我所做的。但现在我赶时间。

希望,有帮助。

答案 2 :(得分:-1)

要直接从文本框文本设置标签内容,我们需要将标签的内容设置为文本框的Text属性

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

要读取标签的设置值,在MyMainWindow是我的usercontrol窗口名称的情况下,可以使用具有INotifyPropertyChanged或Dependency属性的属性直接完成

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

在代码库中,我们将DP定义如下

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

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