以编程方式更改WPF按钮背景图像 [英] Change WPF button background image programmatically

查看:57
本文介绍了以编程方式更改WPF按钮背景图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个< Button/> ,其背景为png图像,背景为彩色.

I'm trying to create a <Button/> with a png image for the background AND a background color.

注意: png图片来源可能尚不清楚,所以我不能只将它们放在模板中.

Note: The png image source may not yet be known, so I can't just put them in the template.

我有一个看起来像这样的 Style :

I've got a Style that looks like this:

<Style x:Key="MyButton" TargetType="Button">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Button">
                <Border CornerRadius="0">
                    <Image Margin="0" Source="/MyApp;component/Images/my-image.png" Stretch="None" />
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Setter Property="Background" Value="LimeGreen" />
                        </Style>
                    </Border.Style>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这给了我一个带按钮的按钮,该按钮在纯LimeGreen背景上具有png图像.

which gives me a button with a png image on top of a solid LimeGreen background.

我的 MainWindow.xaml 看起来像这样:

<Button Style="{StaticResource MyButton}" Click="btnMine_Click" /* some other props */ />

及其背后的代码如下:

private void btnMine_Click(object sender, RoutedEventArgs e)
{
    // TODO: change the image src on this button
    var myButton = sender as Button;

    // This won't work:
    // myButton.Border.Image.Source = getNewImageString();
}

如何将图像源从/MyApp2;component/Images/my-image.png 更改为其他内容?

How do I change the image source from /MyApp2;component/Images/my-image.png to something else?

推荐答案

遗憾的是,在Windows Forms中,它实际上只是一行.在WPF中,看起来将是几百个.

Sigh, in Windows Forms it was literally one line. In WPF it looks like it will be several hundred.

那是因为这是您只能在winforms的按钮中放置的东西.WPF是一个真正的UI框架,不是一些随机的,半弃用的恐龙,只允许做默认的事情(顺便说一下,这太可怕了).

That's because it was the ONLY thing you could place in a button in winforms. WPF is a true UI framework, not some random semi-deprecated dinosaur that only allows to do the default stuff (which by the way looks horrible).

选项1:将图片放置为Button的 Content :

Option 1: Place the Image as Button's Content:

如果您只想在按钮中放置图片,而没有其他选择,为什么不这样做呢?

If you just want to place an Image in the button, and nothing else, why not just do that?

        <Style TargetType="Button">
            <Setter Property="Background" Value="LimeGreen"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}">
                            <ContentPresenter ContentSource="Content"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

然后:

     <Button>
        <!-- Background not set, defaults to what's set in the Style -->
        <Image Source="./ChessPieces/BlackKnight.png"/>
    </Button>
    <Button Background="Red">
        <Image Source="./ChessPieces/BlackBishop.png"/>
    </Button>
    <Button Background="Blue">
        <Image Source="./ChessPieces/BlackPawn.png"/>
    </Button>

    <!-- WPF's idea of "Dynamic" is not the same as win(hack)forms' -->
    <Button Background="White">
        <Image Source="{Binding SomeStringPropertyDefinedInAViewModel}"/>
    </Button>

结果:

选项2(不是很好):使用 Tag 属性:

Option 2 (not very elegant): Use the Tag Property:

如果除了Image之外,您还想在Button内放置其他内容,则可以采用一种有点怪异的方法,将ImageSource放在Button的 Tag 属性中.

If, in addition to the Image, you want to put something else inside the Button, you can resort to a somewhat hacky approach of putting the ImageSource in the Button's Tag property.

        <Style TargetType="Button">
            <Setter Property="Background" Value="LimeGreen"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}">
                            <StackPanel Orientation="Horizontal">
                                <Image Source="{Binding Tag, RelativeSource={RelativeSource TemplatedParent}}"
                                       Height="50" Width="50"/>
                                <ContentPresenter ContentSource="Content"/>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

然后:

    <Button Tag="./ChessPieces/BlackKnight.png"
            Background="Blue"
            Foreground="White"
            Content="Some Text"/>

    <Button Tag="./ChessPieces/BlackBishop.png"
            Background="LightGray">
        <CheckBox Content="A CheckBox!" VerticalAlignment="Center"/>
    </Button>

结果:

选项3:使用附加属性

Option 3: Use an Attached Property

与选项2相同,但是使用在其他地方声明的属性,例如:

Same as option 2, but using a property declared elsewhere, for example:

 <Button ButtonImage.Source="./ChessPieces/BlackBishop.png"
         <!-- etc -->

选项4:创建自定义控件:

创建一个从Button派生的类(没有XAML的.cs文件),并添加一个 DependencyProperty 来保存图像,然后将模板设置为该图像并使用该值.

Create a class (.cs file with no XAML) derived from Button and add a DependencyProperty to hold the image, then set the template to that and use that value.

选项5:MVVM

创建一个 ButtonViewModel ,或实际上使用在声明中声明的 DelegateCommand ViewModel绑定Button的属性.

Create a ButtonViewModel, or actually use a DelegateCommand declared in the ViewModel to bind the Button's properties.

不是一种选择:遍历视觉树并在代码中更改 Image.Source .

Not an Option: Traverse the Visual Tree and change the Image.Source in code.

这不是您要执行的操作.根本不是一个好方法.

That's not something you will want to do. It's not a good approach at all.

我可以永远继续下去,但是我必须去睡觉.如果您想让我详细说明这些方法中的任何一种,请告诉我.

I could go on forever, but I have to go to sleep. If you want me to elaborate on any of these approaches just let me know.

这篇关于以编程方式更改WPF按钮背景图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆