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

Rac*_*hel 5 wpf inheritance xaml coding-style basedon

对于我来说,为数据输入表单的样式编写类似的东西并不罕见,但我的问题是,TextBox并且TextBlock似乎没有实现在中的Setter BaseElementStyle.通常我需要单独定义它们.

为什么是这样?它有办法吗?

我猜它与其他控件模板中常用的事实有关(例如,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}" />
Run Code Online (Sandbox Code Playgroud)

Jin*_*ung 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}" />
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用x:Type

    <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}}" />
    
    Run Code Online (Sandbox Code Playgroud)


F R*_*ell 7

还要记住,WPF认为a ControlTemplate是一个膨胀边界,并且不在模板中应用默认样式.规则的例外:任何继承自Control WILL的东西都会以默认样式膨胀.由于TextBlock继承自FrameworkElementControl而不是继承自Control,如果您在其中使用它,ControlTemplate您还必须手动应用它的样式.对于手动添加的TextBlock或WPF为string添加的TextBlocks都是如此Content.一个简单的例子:

<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>
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此博客文章:

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