Почему мой TextBlock / TextBox не применяет значения из базового стиля? - PullRequest
5 голосов
/ 29 сентября 2011

Я нередко пишу что-то вроде ниже для стилизации формы ввода данных, но моя проблема в том, что TextBox и TextBlock, похоже, не реализуют сеттеры, которые есть в 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}" />

Ответы [ 2 ]

8 голосов
/ 30 сентября 2011

Я хотел бы предложить два возможных обходных пути.Кажется, что каждый из Ключа и Типа может использоваться, но оба из них не могут использоваться вместе, как ваш вопрос, x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}".

  1. , используя x: Ключ

    <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}}" />
    
7 голосов
/ 01 октября 2011

Также следует помнить, что WPF считает ControlTemplate границей инфляции и НЕ применяет стили по умолчанию внутри шаблонов. Исключение из правила: все, что наследуется от Control , БУДЕТ раздутым со стилем по умолчанию. Поскольку TextBlock наследуется от FrameworkElement, а не от Control, если вы используете его внутри ControlTemplate, вам также придется применять его стиль вручную. Это верно как для TextBlocks, добавляемых вручную, так и для TextBlocks, добавляемых WPF для строки 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>

Для получения дополнительной информации см. Этот пост в блоге:

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

...