这两个绑定有什么区别:
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{TemplateBinding Property=Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
和
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
<ContentPresenter />
</Border>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
?
好的......这让我挠头.我有两个WPF控件 - 一个是用户控件,另一个是自定义控件.我们称他们为UserFoo和CustomFoo.在CustomFoo的控件模板中,我使用UserFoo的一个实例,这是一个命名的部分,所以我可以在应用模板后到达它.这很好.
现在,UserFoo和CustomFoo都有一个Text定义的属性(独立地,即不是使用AddOwner的共享DP.不要问...)这两个都被声明为......
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(UserFoo), // The other is CustomFoo
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
null,
null,
true,
UpdateSourceTrigger.PropertyChanged
)
);
Run Code Online (Sandbox Code Playgroud)
请特别注意,模式设置为TwoWay,UpdateSourceTrigger设置为PropertyChanged,两者都设置为.
因此,在CustomFoo的样式模板中,我想将CustomFoo的Text属性绑定为内部UserFoo的Text属性的源.通常,这很容易.你只需将UserFoo的文本属性设置为"{TemplateBinding Text}",但由于某种原因,它只采用一种方式(即从FreeFoo中正确设置UserFoo,但不是相反),即使再次,两个DP都设置为双向!但是,当使用相对源绑定而不是模板绑定时,它工作得很好!嗯......哇?
// This one works
Text="{Binding Text, RelativeSource={RelativeSource AncestorType={local:CustomFoo}}, Mode=TwoWay}"
// As does this too...
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
// But not this one!
Text="{TemplateBinding Text}"
Run Code Online (Sandbox Code Playgroud)
什么给出了什么?我错过了什么?
我正在编写一个WPF控件,它是Button的子类.然后我在Themes\generic.xaml中提供了一个默认样式,它看起来像这样(简化):
<Style TargetType="{x:Type WPFControls:MyButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WPFControls:MyButton}">
<Button
x:Name="PART_Button"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
我希望用户有机会更改控件的背景,但如果他没有,我想提供默认值.我该怎么做?
当我在发布的代码中执行它时,Background和BorderBrush为null(=不存在),除非用户明确指定它们(这有效地强制用户总是提供一些值),但标准的Windows控件(如Button)提供了默认的外观,仍然可以由用户定制.如何在我的控制下做到这一点?
谢谢!
Michael Morton解决方案:
您可以在样式中提供默认设置:
<Style TargetType="{x:Type TestTemplate:MyButton}">
<Setter Property="Background" Value="Red" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TestTemplate:MyButton}">
<Button
x:Name="PART_Button"
IsEnabled="{TemplateBinding IsEnabled}"
Content="{TemplateBinding Content}"
Background="{TemplateBinding Background}"
/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
用法:
<StackPanel>
<TestTemplate:MyButton Background="Blue">Explicitly blue</TestTemplate:MyButton>
<TestTemplate:MyButton>Naturally red</TestTemplate:MyButton>
</StackPanel>
Run Code Online (Sandbox Code Playgroud) 我的按钮有一个标准样式,但我希望样式的某些部分是可配置的.例如,当按钮触发MouseOver时,我会出现边框,我希望边框颜色可配置.
下面这篇文章:http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/我以为我可以使用附加属性和TemplateBinding来实现这一目标.
我创建了以下附加属性:
public static class ThemeProperties
{
public static Brush GetButtonBorderColour(DependencyObject obj)
{
return (Brush)obj.GetValue(ButtonBorderColourProperty);
}
public static void SetButtonBorderColour(DependencyObject obj, Brush value)
{
obj.SetValue(ButtonBorderColourProperty, value);
}
public static readonly DependencyProperty ButtonBorderColourProperty =
DependencyProperty.RegisterAttached(
"ButtonBorderColour",
typeof(Brush),
typeof(ThemeProperties),
new FrameworkPropertyMetadata(Brushes.Black, FrameworkPropertyMetadataOptions.Inherits));
}
Run Code Online (Sandbox Code Playgroud)
我这样设置属性:
<Button Style="{StaticResource RedButton}" local:ThemeProperties.ButtonBorderColour="#B20000"/>
Run Code Online (Sandbox Code Playgroud)
我的风格看起来像这样:
<Window.Resources>
<Style x:Key="RedButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="2"/>
<Setter Property="FontFamily" Value="Tahoma"/>
<Setter Property="FontSize" Value="11px"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="MinHeight" Value="25" />
<Setter Property="FocusVisualStyle" …Run Code Online (Sandbox Code Playgroud) 我正在尝试这样做......
<Style
x:Key="MyBorderStyle"
TargetType="Border">
<Setter
Property="BorderBrush"
Value="{StaticResource MyBorderBrush}" />
<Setter
Property="Background"
Value="{StaticResource MyBackgroundBrush}" />
<Setter
Property="Padding"
Value="{TemplateBinding Padding}" />
</Style>
Run Code Online (Sandbox Code Playgroud)
...但我收到错误: 'Padding' member is not valid because it does not have a qualifying type name.
我如何提供"合格类型名称"?
注意:我试图这样做的原因是,我想在一系列类似的ControlTemplates中包含相同的Border.
谢谢.
编辑:
好吧,我试过这个......
<Setter
Property="Padding"
Value="{TemplateBinding GridViewColumnHeader.Padding}" />
Run Code Online (Sandbox Code Playgroud)
......它实际编译了,但是当我运行应用程序时,我得到了XamlParseException:
Cannot convert the value in attribute 'Value' to object of type ''.
我想,也许有资格Padding与GridViewColumnHeader(这是我想用这种风格与控件模板)的工作,但没有骰子.
编辑2:
那么,根据文档TemplateBinding,它说:
将控件模板中的属性值链接为模板化控件上某些其他公开属性的值.
所以听起来我正在尝试做的事情显然是不可能的.我真的希望能够为我的控件模板中的某些控件创建可重用的样式,但我想模板绑定不能包含在这些样式中.
我有以下控件模板.
我希望使用模板绑定在控件模板中设置图像控件的source属性.
但由于这是按钮控件的控件模板,而按钮控件没有source属性,因此在这种情况下我无法使用TemplateBinding.
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel>
<Image Name="Img" Style="{StaticResource ImageStyle}" Source="temp.jpg" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
由于我必须为不同的按钮实例设置不同的图像,我也不能对路径进行硬编码.
请让我知道如何解决这种情况.
我正在构建一个按钮样式,它依赖于将颜色画笔转换为较暗的阴影来创建阴影.在常规的XAML中,我有一个转换器,而不是我在绑定上使用的转换器完美地工作:
BorderBrush="{Binding Background, Converter={StaticResource ColourBrushToDarker}}"
Run Code Online (Sandbox Code Playgroud)
但我不能让转换器在样式定义中使用TemplateBinding.有办法吗?Visual Studio只允许在TemplateBinding上使用转换器.
我试过以下没有运气:
Background="{Binding Converter={StaticResource ColourBrushToDarker}, ConverterParameter={Binding Path=Background}}"/>
Run Code Online (Sandbox Code Playgroud)
(我已尝试使用TemplateBinding替换Binding以及其他几个迭代的上述行)
可以这样做吗?我想到的另一件事是用C#编写一个执行转换的属性,但是一个样式没有代码隐藏文件.
我之后的结果是能够创建一个比Background属性更暗的新画笔,因此按钮的阴影总是比它的主背景颜色稍暗.
我想创建控制,将采取ItemsSource和InnerTemplate并会显示包裹在所有项目CheckBoxES.
该控件有2个依赖属性:
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CheckBoxWrapperList), null);
public static readonly DependencyProperty InnerTemplateProperty = DependencyProperty.Register("InnerTemplate", typeof(DataTemplate), typeof(CheckBoxWrapperList), null);
Run Code Online (Sandbox Code Playgroud)
这是模板:
<ControlTemplate TargetType="local:CheckBoxWrapperList">
<Grid>
<Grid.Resources>
<DataTemplate x:Key="wrapper">
<CheckBox>
<ContentPresenter ContentTemplate="{TemplateBinding InnerTemplate}" Content="{Binding}" />
</CheckBox>
</DataTemplate>
</Grid.Resources>
<ItemsControl ItemTemplate="{StaticResource wrapper}" ItemsSource="{TemplateBinding ItemsSource}" />
</Grid>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
但是,这种方法不起作用.
在ControlPresenter.ContentTemplate使用TemplateBinding中绑定不起作用.
但是,当我不使用模板绑定并将模板作为静态资源引用时,它会按预期工作.
提前致谢.
我想知道是否可以将像BorderThickness.Top这样的结构元素绑定到TemplatedParent的相应属性.我试过了
<Border Margin="0" Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}">
<Border.BorderThickness>
<Thickness Left="0" Right="0" Top="{TemplateBinding BorderThickness.Top}" Bottom="{TemplateBinding BorderThickness.Bottom}"/>
</Border.BorderThickness>
</Border>
Run Code Online (Sandbox Code Playgroud)
我想要这样做的原因是我希望左和右为0并且只有顶部和底部被绑定.
提前致谢.
我正在WPF中进行自定义控件.我仍然在学习TemplateBinding的内容(在自定义控件中经常使用).
有人认为我注意到我似乎无法在MulitBinding中使用TemplateBinding.
当我尝试这个:
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource MyMultiConverter}">
<Binding ElementName="PART_AComboBox" Path="SelectedItem"/>
<TemplateBinding Property="MyListOne"/>
<TemplateBinding Property="MyListTwo"/>
</MultiBinding>
</ComboBox.ItemsSource>
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
值"System.Windows.TemplateBindingExpression"不是"System.Windows.Data.BindingBase"类型,不能在此通用集合中使用.
参数名称:value
我错过了什么吗?有没有办法让这项工作?
这是我要采取的解决方法,但它有点像黑客:
<ListBox x:Name="ListOne"
ItemsSource="{TemplateBinding MyListOne}"
Visibility="Collapsed" />
<ListBox x:Name="ListTwo"
ItemsSource="{TemplateBinding MyListTwo}"
Visibility="Collapsed" />
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource DictionaryFilteredToKeysConverter}">
<Binding ElementName="PART_TextTemplateAreasHost" Path="SelectedItem"/>
<Binding ElementName="ListOne" Path="ItemsSource"/>
<Binding ElementName="ListTwo" Path="ItemsSource"/>
</MultiBinding>
</ComboBox.ItemsSource>
Run Code Online (Sandbox Code Playgroud)
我将ListBoxes绑定到依赖项属性,然后在我的mulitbinding中,我将一个元素绑定到列表框的ItemsSource.
正如我上面所说,这感觉就像一个黑客,我想知道是否有一个正确的方法来使用TemplateBinding作为组件之一进行MultiBinding.
templatebinding ×10
wpf ×8
xaml ×4
binding ×3
styles ×3
.net ×1
converter ×1
data-binding ×1
datatemplate ×1
default ×1
silverlight ×1
thickness ×1