Как установить стиль текстового блока кнопки WPF из другого ресурса?

#wpf #xaml #controltemplate

#wpf #xaml #controltemplate

Вопрос:

Я устанавливаю в приложении WPF стиль кнопки с помощью этого:

 <Style TargetType="{x:Type Button}">
    <Setter Property="ToolTipService.InitialShowDelay" Value="0"/>
    <Setter Property="Height" Value="22" />
    <Setter Property="Margin" Value="1" />
    <Setter Property="Padding" Value="0" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Padding="{TemplateBinding Padding}"
                        BorderThickness="1">
                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="1 -1 1 0"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Background" Value="{StaticResource NotSelectedButton}" />
    <Setter Property="Foreground" Value="{StaticResource ActiveFg}" />
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="{StaticResource Selected}" />
            <Setter Property="Foreground" Value="{StaticResource SelectedFg}" />
        </Trigger>
        <Trigger Property="IsMouseOver" Value="False">
            <Setter Property="Background" Value="{StaticResource NotSelectedButton}" />
            <Setter Property="Foreground" Value="{StaticResource ActiveFg}" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource NotSelectedButton}" />
            <Setter Property="Foreground" Value="{StaticResource InactiveFg}" />
            <!--<Setter Property="Foreground" Value="{StaticResource NotSelected}" />-->
        </Trigger>
    </Style.Triggers>
</Style>
  

Однако я хочу TextBlock , чтобы в ContentPresenter использовать именованный TextBlock стиль, определенный как таковой:

 <Style x:Key="ButtonText" TargetType="{x:Type TextBlock}">
    <Setter Property="ToolTipService.InitialShowDelay" Value="0"/>
    <Setter Property="Width" Value="auto" />
    <Setter Property="MinWidth" Value="20" />
    <Setter Property="TextAlignment" Value="Left" />
    <Setter Property="Padding" Value="0 0 0 0" />
    <Setter Property="Margin" Value="1 0 0 0" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="HorizontalAlignment" Value="Center" />
</Style>
  

Чтобы протестировать этот стиль, достаточно просто a Button в UserControl or Window : <Button> , а определения стилей могут быть помещены в словарь ресурсов (из UserControl or Window ).

Как я могу это сделать?

Ответ №1:

Тривиальное решение с помощью прямого назначения

Вы можете установить стиль напрямую, назначив TextBlock значение as Content для каждого Button .

 <Button>
   <TextBlock Text="Test" Style="{StaticResource ButtonText}"/>
</Button>
  

Поддержка текста только как содержимого

Если вы уверены, что помещаете только строки в качестве содержимого в свою кнопку, вы можете назначить a ContentTemplate , который содержит a TextBlock для ContentPresenter . Это не будет работать для других типов контента в том смысле, что он не будет отображать их как обычно, а только их имя типа в TextBlock .

 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="1 -1 1 0">
   <ContentPresenter.ContentTemplate>
      <DataTemplate>
         <TextBlock Style="{StaticResource ButtonText}" Text="{Binding}"/>
      </DataTemplate>
   </ContentPresenter.ContentTemplate>
</ContentPresenter>
  

Поддержка всех типов контента

Если вы хотите поддерживать любой тип контента в качестве содержимого вашей кнопки, вы можете определить шаблон данных сверху в ContentPresenter.Resources . Затем ContentPresenter он будет применяться только в том случае, если Content это a string . Для всех других типов контента это будет работать как обычно.

 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="1 -1 1 0">
   <ContentPresenter.Resources>
      <DataTemplate DataType="{x:Type system:String}">
         <TextBlock Style="{StaticResource ButtonText}" Text="{Binding}"/>
      </DataTemplate>
   </ContentPresenter.Resources>
</ContentPresenter>
  

Комментарии:

1. Последний вариант с ContentPresenter. Ресурсы идеальны.