Template Binding with Attached Properties
我的按钮具有标准样式,但是我希望样式的某些部分是可配置的。 例如 当为按钮触发MouseOver时,出现边框,并且希望边框颜色可配置。
紧随本文之后:http://www.thomaslevesque.com/2011/10/01/wpf-creating-parameterized-styles-with-attached-properties/我认为我可以使用附加属性和TemplateBinding来实现此目的。
我创建了以下附加属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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)); } |
我将属性设置如下:
1 | <Button Style="{StaticResource RedButton}" local:ThemeProperties.ButtonBorderColour="#B20000"/> |
我的风格如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | <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" Value="{StaticResource MyFocusVisual}" /> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="#FECCBF" Offset="0.2"/> <GradientStop Color="Red" Offset="0.85"/> <GradientStop Color="#FECCBF" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border Name="border" BorderThickness="1" Padding="4,2" BorderBrush="Transparent" CornerRadius="3" Background="{TemplateBinding Background}"> <Grid > <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Name="content"/> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding local:ThemeProperties.ButtonBorderColour}" /> <Setter Property="Foreground" Value="#B20000" /> </Trigger> <Trigger Property="IsPressed" Value="True"> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="#FECCBF" Offset="0.35"/> <GradientStop Color="Red" Offset="0.95"/> <GradientStop Color="#FECCBF" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> <Setter TargetName="content" Property="RenderTransform"> <Setter.Value> <TranslateTransform Y="1.0" /> </Setter.Value> </Setter> </Trigger> <Trigger Property="IsDefaulted" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="#B20000" /> </Trigger> <Trigger Property="IsFocused" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="#B20000" /> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="border" Property="Opacity" Value="0.7" /> <Setter Property="Foreground" Value="Gray" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> |
关键线在哪里
1 2 3 4 | <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding local:ThemeProperties.ButtonBorderColour}" /> <Setter Property="Foreground" Value="#B20000" /> </Trigger> |
据我所知,这应该起作用,但是在运行过程中,在上面的行中出现以下错误:
Cannot convert the value in attribute 'Value' to object of type ''.
Error at object 'System.Windows.Setter' in markup file
我在这里做错了什么吗? 我是WPF的新手,无法弄清楚出了什么问题,因为附加属性的Type是Brush,这是我期望Border的BorderBrush属性所需要的。
我认为TemplateBinding是在编译时评估的,因此您不能在Setter中动态设置TemplateBinding,请尝试使用Binding(请参见下文)。
1 2 3 | <Setter TargetName="border" Property="BorderBrush" Value="{Binding Path=(local:ThemeProperties.ButtonBorderColour), RelativeSource={RelativeSource TemplatedParent}}"/> |
希望这可以帮助。
试试这个:
1 | <Setter TargetName="border" Property="BorderBrush" Value="{TemplateBinding Path=(local:ThemeProperties.ButtonBorderColour)}" /> |
区别在于,属性的括号表示该属性是附加属性。