【问题标题】:Button Background Margin按钮背景边距
【发布时间】:2021-02-03 11:12:36
【问题描述】:

我正在寻找一种在具有专用边距的按钮中添加背景图像的方法。现在我有这样的东西:

<Button Grid.Column="3" Margin="2,0">
    <Button.Background>
        <ImageBrush Stretch="Fill" TileMode="None">
            <ImageBrush.ImageSource>
                <DrawingImage Drawing="{StaticResource MyImage}" />
            </ImageBrush.ImageSource>
        </ImageBrush>
    </Button.Background>
</Button>

这会用图像完全填充我的按钮。这是(我认为......)正确的行为。现在我想在背景图像周围留一个小边距。我没有找到这样做的方法,因为图像画笔和绘图图像都没有提供这样的属性。我知道我可以使用按钮内容来制作提供边距的图像,但是通过这种方法,当我将按钮放在滚动查看器控件中时,按钮图像的行为很奇怪(当我调整视图大小时按钮会增长,但是图像保持小)。处理这个问题的最佳方法是什么?

  • 更新 *

根据下面的答案,自定义样式似乎是最合适的。无论如何,也许我的问题实际上不是按钮本身,而是按钮周围的滚动查看器。我已经附加了两个图像,第一个带有滚动视图,第二个没有。使用滚动查看器,图像很小,不适合按钮,所以这可能是这里的根本原因?任何建议:

没有滚动查看器:

【问题讨论】:

  • 看来需要设置Padding
  • 我想我找到了滚动查看器问题的问题。这是缺少属性“Horizo​​ntalContentAlignment”和“VerticalContentAlignment”到“Stretch”。有时 WPF 让我非常疯狂:-)

标签: c# wpf xaml wpf-controls


【解决方案1】:

设置Padding,Margin用于设置控件外部的间距,而Padding用于在有界控件内部提供空间,你应该做以下事情,

  1. 您必须设置 Content 而不是 Background 属性 按钮的属性。
  2. 使用 Image 控件代替 ImageBrush 作为按钮内容。
<Button
        Grid.Column="3"
        Width="300"
        Height="30"
        Margin="2,0"
        Padding="5"
        HorizontalContentAlignment="Stretch"
        VerticalContentAlignment="Stretch"
        BorderBrush="Red"
        Style="{DynamicResource ButtonStyle1}">
    <Button.Content>
        <Image Source="in.png" Stretch="Fill" />
    </Button.Content>
</Button>

【讨论】:

    【解决方案2】:

    在此处设置MarginPadding 将不起作用Margin 应用于按钮周围,而不是按钮中,Padding 应用于内部ContentPresenter。换句话说,填充将在Content 周围,但不在Background 周围,因为那不是内容的一部分。

    您解决问题的选择是:

    • 创建一个已经包含边距的绘图(在重新缩放时不会保持不变)。

    • 将图像创建为Button 的内容,然后Padding 将起作用(推荐)。

      <Button Grid.Column="3" Padding="2, 0">
         <Button.Content>
            <Image Stretch="Fill">
               <Image.Source>
                  <DrawingImage Drawing="{StaticResource MyImage}" />
               </Image.Source>
            </Image>
         </Button.Content>
      </Button>
      
    • 编辑默认控件模板和样式以更改应用背景的方式。这可能很乏味,并且会影响其他视觉状态,而不仅仅是静态状态,因此如果您选择这样做,请务必小心。这是一个示例它的外观。

      <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
      <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
      <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
      <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
      <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
      <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
      <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
      <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
      <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
      <Style x:Key="FocusVisual">
         <Setter Property="Control.Template">
            <Setter.Value>
               <ControlTemplate>
                  <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
      <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
         <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
         <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
         <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
         <Setter Property="BorderThickness" Value="1"/>
         <Setter Property="HorizontalContentAlignment" Value="Center"/>
         <Setter Property="VerticalContentAlignment" Value="Center"/>
         <Setter Property="Padding" Value="1"/>
         <Setter Property="Template">
            <Setter.Value>
               <ControlTemplate TargetType="{x:Type Button}">
                  <Border x:Name="border" Padding="{TemplateBinding Padding}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
                     <Border x:Name="innerBorder" Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                     </Border>
                  </Border>
                  <ControlTemplate.Triggers>
                     <Trigger Property="IsDefaulted" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                     </Trigger>
                     <Trigger Property="IsMouseOver" Value="true">
                        <Setter Property="Background" TargetName="innerBorder" Value="{StaticResource Button.MouseOver.Background}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
                     </Trigger>
                     <Trigger Property="IsPressed" Value="true">
                        <Setter Property="Background" TargetName="innerBorder" Value="{StaticResource Button.Pressed.Background}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
                     </Trigger>
                     <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Background" TargetName="innerBorder" Value="{StaticResource Button.Disabled.Background}"/>
                        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                        <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
                     </Trigger>
                  </ControlTemplate.Triggers>
               </ControlTemplate>
            </Setter.Value>
         </Setter>
      </Style>
      

      如果将这些样式放在范围内的资源字典中,则可以这样使用。

      <Button Grid.Column="3" Style="{StaticResource ButtonStyle}" Padding="20, 0">
         <Button.Background>
            <ImageBrush Stretch="Fill" TileMode="None">
               <ImageBrush.ImageSource>
                  <DrawingImage Drawing="{StaticResource MyImage}" />
               </ImageBrush.ImageSource>
            </ImageBrush>
         </Button.Background>
      </Button>
      

      当然,如果您省略样式键,您也可以根据需要将其设为隐式。

    【讨论】: