Стили наведения мыши на кнопках WPF со смешанным содержимым

У меня есть стандартный Button Style, применяемый к моему приложению, который определяет стиль наведения мыши, который меняет текстовое содержимое с белого на черный. Для этого я попытался изменить шаблон кнопки, удалив ContentPresenter и заменив его на TextBlock. Однако это означает, что я не могу иметь смешанный контент, например:

<Button
    <Button.Content>
        <StackPanel Orientation="Horizontal">
            <Path Margin="3" Width="12.375" Height="9.70833" Canvas.Left="0" Canvas.Top="0"
                  Stretch="Fill" Fill="#FF115485"
                  Data="F1 M 18.8333,7.08333L 16.7083,4.91667L 10.5,10.5417L 8.52083,8.6875L 6.45833,10.4792L 10.4792,14.625L 18.8333,7.08333 Z "/>
            <TextBlock Margin="3">Hello</TextBlock>
        </StackPanel>
    </Button.Content>
</Button>

Чтобы исправить ситуацию, я снова вставил ContentPresenter и на своих (только текстовых) кнопках указал ContentTemplate следующим образом:

<Button IsDefault="True" Content="Text only Button"
        ContentTemplate="{StaticResource TextButtonTemplate}"
        Command="{Binding ...}" 
        CommandParameter="{...}" />

И с Template, определенным, как показано ниже. Этот шаблон будет работать только для Buttons с текстовым содержимым, а другие шаблоны определяются по мере необходимости для смешанного содержимого.

<DataTemplate x:Key="TextButtonTemplate">
    <TextBlock Text="{TemplateBinding Content}"
               Foreground="{Binding Path=Foreground,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Button}}" />
</DataTemplate>

Кто-нибудь знает, есть ли способ улучшить это, сохранив желаемый стиль наведения мыши без необходимости определять пользовательские шаблоны?


person Justin Brown    schedule 28.10.2009    source источник


Ответы (1)


Предполагая, что контент сам по себе явно не устанавливает какие-либо цвета, вы можете сделать это следующим образом:

<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
    <Style.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="TextBlock.Foreground" Value="Red" />
        </Trigger>
    </Style.Triggers>
</Style>

Это работает, потому что TextBlock.Foreground является унаследованным свойством. Пока элементы управления внутри содержимого вашей кнопки явно не устанавливают свой собственный передний план, это будет работать. Если они устанавливают свои собственные цвета, все ставки сняты.

person Drew Marsh    schedule 28.10.2009
comment
Спасибо за отличный ответ. Раньше я ничего не делал с унаследованными свойствами. К сожалению, мои TextBlocks устанавливают свои собственные цвета, так как я не хочу, чтобы они использовали системные значения по умолчанию. Возможно, мне придется опубликовать новый вопрос об этом..... - person Justin Brown; 04.11.2009