WPF图像按钮格式化

26

如果我创建一个带有图像的按钮,它会被放大到比图像大得多的尺寸。

如果我尝试限制图像和容器按钮的大小,则图像将被裁剪:

<Button Background="Transparent" Width="18" Height="18" Margin="0,0,0,0" Padding="0,0,0,0" BorderBrush="{x:Null}">
    <Image Width="16" Height="16" />
</Button>

原生图像大小为16x16。这里按钮的大小为18x18,没有填充,但图像仍然在右侧/底部被裁剪。

我该如何使整个按钮的大小正好等于图像大小,而没有任何裁剪?

4个回答

52

WPF的美丽(和诅咒?)在于能够重新定义控件的模板。

你可以像下面这样设置按钮的模板(这是手写的,所以你需要根据自己的喜好进行微调):

        <Button x:Name="btn16x16">
            <Button.Template>
                <ControlTemplate>
                    <Border HorizontalAlignment="Center" VerticalAlignment="Center" >
                        <Image Source="pack://siteoforigin:,,,/Resources/SixteenBySixteen.png" 
                               Width="16" 
                               Height="16"/>
                    </Border>
                </ControlTemplate>
            </Button.Template>
        </Button>

12

你应该移除任何WidthHeight设置,并将按钮的HorizontalAlignmentVerticalAlignment都设置为Center(或Left/RightTop/Bottom)。默认情况下,这些属性被设置为Stretch,这使得按钮会被拉伸到可用空间大小。因为图片是按钮的内容,所以它也会被拉伸。像这样设置应该可以解决问题:

拿这段代码示例为例:

<Button Background="Transparent" BorderBrush="{x:Null}" HorizontalAlignment="Center" VerticalAlignment="Center">
    <Image Source="thePathToYourImage" Stretch="None"/> <!-- EDIT: added Stretch="None" here! -->
</Button>

如果你希望按钮可以拉伸,但是不希望图像也跟着被拉伸,你可以将Image的对齐属性设置为Stretch以外的其他值。或者你可以将其Stretch属性设置为None。这将使按钮尽可能大,但保持图像原始大小(16x16)。这将按照以下方式工作:

<Button Background="Transparent" BorderBrush="{x:Null}">
    <Image Source="thePathToYourImage" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
<!-- OR: -->
<Button Background="Transparent" BorderBrush="{x:Null}">
    <Image Source="thePathToYourImage" Stretch="None"/>
</Button>


你有看过我的第一个代码示例吗?第二个只是另一种选择。你应该正确设置Button的对齐属性,然后按钮应该根据其内容大小调整大小,即图像。 - gehho
是的,我有。这没有任何区别。与默认值相同。我的代码: - Sonic Soul
但是,将水平对齐和垂直对齐设置为居中,并将图像宽度和按钮宽度设置为16x16,就接近了!唯一剩下的问题是在鼠标悬停和选择包含行时仍然显示奇怪的边框... - Sonic Soul
@Sonic Soul:你有看过我的回答吗?还是随意复制了一些代码?请先阅读XAML之前的段落!并选择第一个代码示例,而不是第二个。我认为我会编辑答案,使其更加清晰明了... - gehho
刚在 Blend 中检查了代码。您需要将按钮的 HorizontalAlignmentVerticalAlignment 设置为 Center并且ImageStretch 属性设置为 None,因为此属性默认为 Uniform,会将图像放大到最大。请参见我在原始答案中编辑的代码示例以获取可工作的示例。 - gehho
显示剩余3条评论

12
你可以像这样使用Button.BackgroundImageBrush作为示例:
<Button Height="24" Width="24" >
    <Button.Background>
        <ImageBrush ImageSource="image name or path" Stretch="Fill" TileMode="None" />
    </Button.Background>
</Button>

我认为这是最好的方法。但是,如果您像OP所说使用16x16图标,则必须小心设置按钮的高度和宽度以确保不会压缩图像。我认为这是最干净的方法,因此我最喜欢这个答案。 - Mike G
4
采用这种方法时,当我将鼠标悬停在图像上时,图像会逐渐变淡并消失不见。 - RickNZ
我的情况更糟糕——我只是在现有表单中添加了一个全新的按钮——很确定没有任何代码涉及它——但是图像在可见和不可见之间缓慢闪烁——也许是因为我将按钮的IsDefault设置为true?——毫无头绪。这有点疯狂。 - BrainSlugs83

0

想要实现没有边框的带图片按钮吗?this 可能会给你答案。


这不是和Wonko的建议一样吗?我猜如果其他方法都失败了,在WPF中需要通过控件模板来处理图像按钮。 - Sonic Soul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接