我怎样才能*不*禁用禁用按钮内容中的边框?

How can I *not* disable a border in the contents of a disabled button?

我有一排按钮,我在其中使用背景来表示简单色样的颜色。问题是当按钮被禁用时,它通过样式覆盖背景,完全用相同的灰色替换颜色,所以你不仅看不到颜色,而且它们看起来都像占位符,因为它们没有任何其他内容.

这里都启用了...

这里他们都被禁用了...

在一个完美的世界里,我希望他们调暗背景,而不是 removed/overwrote,但如果它什么也没做我会很高兴。

现在我知道我可以重新设置按钮模板的样式,但我想知道是否有一种方法可以说“不要根据 enabled/disabled 更新视觉样式”而不必执行所有操作那。简单地调暗它们也是合适的,但像这样完全更换它们是一个问题。

那么有这样的事情吗,还是我必须重新制作按钮模板?

目前,我的技巧是删除命令的 CanExecute 检查以使其始终处于启用状态,然后只需在命令的 Executed 处理程序中进行处理(或不进行处理)。

如您所说,设置按钮的 Background 将不起作用,因为默认样式和控件模板将覆盖 鼠标悬停[=52= 等状态下的背景]、已按下已禁用

比创建自定义模板更轻量级的变体是使用内容模板创建 Button 将颜色显示为 Content 的样式。如果内容类型是 BrushBorder 将显示颜色。触发器确保 Opacity 根据父 Button.

IsEnabled 进行调整
<Style x:Key="ColorSwatchButtonStyle"  TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
   <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
   <Setter Property="VerticalContentAlignment" Value="Stretch"/>
   <Setter Property="ContentTemplate">
      <Setter.Value>
         <DataTemplate DataType="{x:Type Brush}">
            <Border Background="{Binding}">
               <Border.Style>
                  <Style TargetType="{x:Type Border}">
                     <Setter Property="Opacity" Value="1.0"/>
                     <Style.Triggers>
                        <DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="False">
                           <Setter Property="Opacity" Value="0.3"/>
                        </DataTrigger>
                     </Style.Triggers>
                  </Style>
               </Border.Style>
            </Border>
         </DataTemplate>
      </Setter.Value>
   </Setter>
</Style>

如果您不想在 Border 中添加样式,请改用数据模板触发器。

<Style x:Key="ColorSwatchButtonStyle"  TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
   <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
   <Setter Property="VerticalContentAlignment" Value="Stretch"/>
   <Setter Property="ContentTemplate">
      <Setter.Value>
         <DataTemplate DataType="{x:Type Brush}">
            <Border x:Name="ColorBorder"  Background="{Binding}"/>
            <DataTemplate.Triggers>
               <DataTrigger Binding="{Binding IsEnabled, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="False">
                  <Setter TargetName="ColorBorder" Property="Opacity" Value="0.3"/>
               </DataTrigger>
               <DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
                  <Setter TargetName="ColorBorder" Property="Opacity" Value="0.8"/>
               </DataTrigger>
               <DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
                  <Setter TargetName="ColorBorder" Property="Opacity" Value="0.5"/>
               </DataTrigger>
            </DataTemplate.Triggers>
         </DataTemplate>
      </Setter.Value>
   </Setter>
</Style>

显式应用样式或删除 x:Key 以使样式隐式并将其应用于范围内的所有按钮。将颜色设置为ButtonContent

<Button Style="{StaticResource ColorSwatchButtonStyle}"
        Content="{x:Static Brushes.Red}"/>

作为此方法的注意事项,由于内容 Border 遮挡了按钮的背景,您将看不到上述状态的效果。但是,您可以向此样式添加触发器以在 鼠标悬停按下 状态下适当地显示您的颜色。

<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
   <Setter Property="Opacity" Value="0.8"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsPressed, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" Value="True">
   <Setter Property="Opacity" Value="0.5"/>
</DataTrigger>

这只是一个示例,当然,您也可以更改BorderBrushBorderThickness或者在模板中添加其他元素。您不仅限于更改 Opacity


或者,您始终可以复制默认样式和控件模板 using Blend or Visual Studio。然后您可以调整按钮的受影响状态以不同方式显示 Background

如果您想禁用 Button 而不改变其外观,您可以将 IsHitTestVisible 设置为 false 而不是设置 IsEnabled 属性 .

然后您可以使用 Opacity 属性 进行调光。

另一种选择是创建自定义 ControlTemplate