覆盖 XAML 中的控件模板属性
Posted
技术标签:
【中文标题】覆盖 XAML 中的控件模板属性【英文标题】:override control template property in XAML 【发布时间】:2015-09-07 19:36:24 【问题描述】:如果我在 generic.xaml 中定义了以下 XAML
<Style TargetType="x:Type TextBox">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="CaretBrush" Value="StaticResource TextBoxCaretBrush" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="None" />
<Setter Property="FocusVisualStyle" Value="x:Null" />
<Setter Property="MinWidth" Value="120" />
<Setter Property="MinHeight" Value="20" />
<Setter Property="AllowDrop" Value="True" />
<Setter Property="Foreground" Value="StaticResource TextBoxTextBrush" />
<Setter Property="Padding" Value="5,3,0,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="x:Type TextBoxBase">
<Border x:Name="Border" CornerRadius="5" Padding="2" BorderThickness="1">
<Border.Background>
<SolidColorBrush Color="StaticResource TextBoxBackgroundColor" />
</Border.Background>
<Border.BorderBrush>
<SolidColorBrush Color="StaticResource TextBoxBorderColor" />
</Border.BorderBrush>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="StaticResource DisabledControlLightColor" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ReadOnly">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="StaticResource DisabledControlDarkColor" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="Border" Value="StaticResource TextBoxBorderSelectedBrush" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="StaticResource HighlightColor" Opacity="1" BlurRadius="5" />
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
在我看来,我已经定义了以下 XAML 以使用上述样式显示 TextBox。
<TextBox Name="UserName" attachedProperties:KeyboardNavigationExt.TabOnEnter="True" Grid.Row="1" KeyboardNavigation.TabIndex="1" Grid.Column="2" Grid.ColumnSpan="3" cal:Message.Attach="[Event TextChanged] = [Action CanLogin]" />
这会在视图上显示一个 TextBox,Template
中的 Border
上的 CornerRadius
为 5。
现在我的问题是,我有一个场景,其中有两个 TextBox 彼此相邻,我想为两个 TextBox 指定CornerRadius
,如下所示。
<TextBox Name="UserName" CornerRadius="5,5,0,0" attachedProperties:KeyboardNavigationExt.TabOnEnter="True" Grid.Row="1" KeyboardNavigation.TabIndex="1" Grid.Column="2" Grid.ColumnSpan="3" cal:Message.Attach="[Event TextChanged] = [Action CanLogin]" />
但是 TextBox 没有 CornerRadius
我该如何实现这一点,以便我能够在视图 XAML 中更改 Border
的 CornerRadius
【问题讨论】:
创建另一个附加属性(代理),就像您对KeyboardNavigationExt.TabOnEnter
所做的那样,但这是CornerRadius
类型的一个,在Style
中设置默认值,并在模板中将ConrnerRadius
绑定到该属性TemplatedParent
的附加属性。像这样,您将能够更改每个 TextBox
的值。检查this答案
如何在模板中绑定它?我试过CornerRadius="TemplateBinding CornerRadius"
,但我得到一个错误
查看之前评论中答案的链接。你使用RelativeSource
到TemplatedParent
绑定
谢谢,这就是我遗漏的一点,我完全错过了您上面评论中的链接,如果您添加您的答案,那么我可以标记为答案
【参考方案1】:
正如评论中提到的,您需要可以针对TextBox
设置的代理属性并在模板中绑定。所以创建AttachedProprty
的CornerRadius
类型
public static class AttachedProperties
public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached("CornerRadius", typeof(CornerRadius), typeof(AttachedProperties), new UIPropertyMetadata());
public static void SetCornerRadius(DependencyObject d, CornerRadius source)
d.SetValue(CornerRadiusProperty, source);
public static CornerRadius GetCornerRadius(DependencyObject d)
return (CornerRadius)d.GetValue(CornerRadiusProperty);
更改ControlTemplate
并绑定到TemplatedParent
的该属性
<ControlTemplate TargetType="x:Type TextBox">
<Border CornerRadius="Binding RelativeSource=RelativeSource TemplatedParent, Path=(local:AttachedProperties.CornerRadius)"/>
</ControlTemplate>
使用默认值将Setter
添加到您的Style
<Setter Property="local:AttachedProperties.CornerRadius" Value="5"/>
然后您可以针对每个 TextBox
手动更改它
<TextBox local:AttachedProperties.CornerRadius="5,5,0,0" .../>
【讨论】:
以上是关于覆盖 XAML 中的控件模板属性的主要内容,如果未能解决你的问题,请参考以下文章
Silverlight Xaml 覆盖控件的 IsEnabled 属性