WPF:将属性绑定到样式中的对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32926063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF: Binding Property to an object in Style
提问by Shahryar
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:
在后面的代码中,我将此函数编写为 Label 对象的新属性,以将 LContent 值绑定到标签对象:
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?
但标签内容不会改变。你能帮助我吗?
回答by slugster
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 sheetmight 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.
这份备忘单可能是您的宝贵参考。上一个 SO 问题什么是模板绑定与绑定?也有一个很好的简单例子。
回答by Manish Singh
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
首先,我不确定是x:Key="{x:Type TextBox}"做什么的,但请确保正确设置了数据上下文。就像你在窗口中使用它一样
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 LabelContentand you are using LContent in the Binding. Changing it to LabelContent can help.
而且我还注意到您已将属性名称注册为LabelContent并且您在绑定中使用 LContent。将其更改为 LabelContent 会有所帮助。
<Label x:Name="label" Content="{Binding LabelContent}" >
You've set you're TargetTypeto 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.
您已将TargetType设置为 TextBox 并且即使您的自定义控件派生自 TextBox 它也不会应用于它,您应该直接指定您的自定义控件类名称CustomTextBox。
To make things clear, I would say that If you've a x:Key attribute in you're style, if will not automatically get applied to all the targetTypeelement. Then you have to explicitly specify the style for each control.
为了清楚起见,我会说,如果您的样式中有 ax:Key 属性,则 if 不会自动应用于所有targetType元素。然后您必须明确指定每个控件的样式。
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.
希望能帮助到你。
回答by Dinesh_MoveOn
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
要直接从文本框文本中设置标签内容,我们需要将标签的内容设置为文本框的Text属性
<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
要读取标签的设置值,在 MyMainWindow 是我的用户控件窗口名称的情况下,可以直接使用带有 INotifyPropertyChanged 或 Dependency 属性的属性来完成
<TextBox Grid.Row="0" x:Name="CustomizedTextBox" Text="{Binding ElementName=MyMainWindow, Path=LabelContent }"
In Code base we have DP defined as below
在代码库中,我们定义了如下 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); }
}

