当内容为 StackPanel 时,按钮前景不会改变
Button foreground doesn't change when content is StackPanel
我定义了一个按钮样式,其中模板具有名称为 "contentPresenter" 的 ContentPresenter。然后它有一个触发器设置如下:
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383" />
</Trigger>
</ControlTemplate.Triggers>
当按钮被禁用时,此触发器只是将按钮的前景色更改为灰色。但是,我的应用程序中有一个按钮,其内容不是简单的文本。该按钮如下所示:
<Button Grid.Column="3" Grid.Row="3" Grid.ColumnSpan="2"
Margin="120 20 30 10"
Command="{Binding SomeCommand}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MyImage}" Margin="0 0 2 0"
Visibility="{Binding ShowMyImage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBlock Text="{Binding ButtonText}" />
</StackPanel>
</Button>
无论按钮是否被禁用,该按钮的前景始终相同。我在想这是因为按钮的文本位于内容演示器堆栈面板内的文本块中,但我不知道如何将前景色更改应用于内部文本块。
我尝试将触发器中的 属性 更改为使用 "TextBlock.Foreground" 而不是 "TextElement.Foreground"。我还尝试将内部文本块的前景绑定到 FrameworkElement 类型的最近祖先的前景颜色,如下所示:
<TextBlock Text="{Binding ButtonText}" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(FrameworkElement.Foreground)}" />
None 这行得通。我需要做什么才能将前景色应用于 StackPanel 内的 TextBlock?
您的触发器应该在样式中,并且应该在按钮本身上设置前景,而不是在 ContentPresenter 上。然后它就会正常工作,使用自定义模板或默认模板。不需要任何额外的绑定。
<Style TargetType="Button" x:Key="MyButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Beige" BorderBrush="Black" BorderThickness="1" Padding="6,2">
<ContentPresenter
/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FF838383" />
</Trigger>
</Style.Triggers>
</Style>
用法:
<Button
IsEnabled="False"
Style="{StaticResource MyButtonStyle}"
>
<StackPanel>
<TextBlock
>Blah Blah</TextBlock>
<Button>X</Button>
</StackPanel>
</Button>
<Button Style="{StaticResource MyButtonStyle}" IsEnabled="False">Testing</Button>
截图(别管我丑陋的模板):
我定义了一个按钮样式,其中模板具有名称为 "contentPresenter" 的 ContentPresenter。然后它有一个触发器设置如下:
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#FF838383" />
</Trigger>
</ControlTemplate.Triggers>
当按钮被禁用时,此触发器只是将按钮的前景色更改为灰色。但是,我的应用程序中有一个按钮,其内容不是简单的文本。该按钮如下所示:
<Button Grid.Column="3" Grid.Row="3" Grid.ColumnSpan="2"
Margin="120 20 30 10"
Command="{Binding SomeCommand}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding MyImage}" Margin="0 0 2 0"
Visibility="{Binding ShowMyImage, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBlock Text="{Binding ButtonText}" />
</StackPanel>
</Button>
无论按钮是否被禁用,该按钮的前景始终相同。我在想这是因为按钮的文本位于内容演示器堆栈面板内的文本块中,但我不知道如何将前景色更改应用于内部文本块。
我尝试将触发器中的 属性 更改为使用 "TextBlock.Foreground" 而不是 "TextElement.Foreground"。我还尝试将内部文本块的前景绑定到 FrameworkElement 类型的最近祖先的前景颜色,如下所示:
<TextBlock Text="{Binding ButtonText}" Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(FrameworkElement.Foreground)}" />
None 这行得通。我需要做什么才能将前景色应用于 StackPanel 内的 TextBlock?
您的触发器应该在样式中,并且应该在按钮本身上设置前景,而不是在 ContentPresenter 上。然后它就会正常工作,使用自定义模板或默认模板。不需要任何额外的绑定。
<Style TargetType="Button" x:Key="MyButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Beige" BorderBrush="Black" BorderThickness="1" Padding="6,2">
<ContentPresenter
/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#FF838383" />
</Trigger>
</Style.Triggers>
</Style>
用法:
<Button
IsEnabled="False"
Style="{StaticResource MyButtonStyle}"
>
<StackPanel>
<TextBlock
>Blah Blah</TextBlock>
<Button>X</Button>
</StackPanel>
</Button>
<Button Style="{StaticResource MyButtonStyle}" IsEnabled="False">Testing</Button>
截图(别管我丑陋的模板):