我为类似数据输入表单的样式编写类似下面的内容并不少见,但我的问题是TextBox
和TextBlock
似乎没有实现{BaseElementStyle
中的Setter 1}}。通常我需要单独定义它们。
这是为什么?它有办法吗?
我猜这与它们通常在其他控件模板中使用的事实有关(例如,TextBlock用于大多数控件,而TextBox用于DatePickers和ComboBoxes)
<Style x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="5" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseElementStyle}" />
答案 0 :(得分:8)
我想建议两种可能的解决方法。似乎可以使用Key和Type中的每一个,但它们不能一起用作问题案例x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}"
。
使用x:Key
<Style x:Key="BaseElementStyle">
<Setter Property="FrameworkElement.Margin" Value="5" />
<Setter Property="FrameworkElement.VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseElementStyle}" />
使用x:输入
<Style TargetType="{x:Type FrameworkElement}">
<Setter Property="Margin" Value="5" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
答案 1 :(得分:7)
另请注意,WPF认为ControlTemplate
是一个通胀边界,并且 NOT 在模板中应用默认样式。规则的例外:从Control
继承的任何内容都将用默认样式进行膨胀。由于TextBlock
继承自FrameworkElement
而不是来自Control,如果您在ControlTemplate
内使用它,则还必须手动应用它的样式。对于手动添加的TextBlock或由WPF为字符串Content
添加的TextBlocks都是如此。一个简单的例子:
<Window x:Class="ImplicitStyles.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<StackPanel.Resources>
<Style x:Key="BaseElementStyle">
<Setter Property="FrameworkElement.Tag" Value="Hello World" />
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseElementStyle}" />
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" />
<!-- Default style for TextBlock will not be applied, Tag will be null -->
<ControlTemplate x:Key="MyContentControlTemplateOne" TargetType="{x:Type ContentControl}">
<Border BorderBrush="Red" BorderThickness="2">
<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" />
</Border>
</ControlTemplate>
<!-- Default style for Button will be applied, Tag will be Hello World -->
<ControlTemplate x:Key="MyContentControlTemplateTwo" TargetType="{x:Type ContentControl}">
<Border BorderBrush="Red" BorderThickness="2">
<Button Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" />
</Border>
</ControlTemplate>
</StackPanel.Resources>
<ContentControl Template="{StaticResource MyContentControlTemplateOne}" />
<ContentControl Template="{StaticResource MyContentControlTemplateTwo}" />
</StackPanel>
</Window>
有关详细信息,请参阅此博文: