为什么我的TextBlock / TextBox不能应用基本样式的值?

时间:2011-09-29 12:39:26

标签: wpf xaml inheritance coding-style basedon

我为类似数据输入表单的样式编写类似下面的内容并不少见,但我的问题是TextBoxTextBlock似乎没有实现{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}" />

2 个答案:

答案 0 :(得分:8)

我想建议两种可能的解决方法。似乎可以使用Key和Type中的每一个,但它们不能一起用作问题案例x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}"

  1. 使用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}" />
    
  2. 使用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>

有关详细信息,请参阅此博文:

http://blogs.msdn.com/b/wpfsdk/archive/2009/08/27/implicit-styles-templates-controls-and-frameworkelements.aspx