以编程方式更改 WPF 按钮背景图像

2023-12-10

我正在尝试创建一个<Button/>以 png 图像作为背景和背景颜色。

Note: The PNG图像来源可能还不知道,所以我不能只是将它们放入模板中。

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

<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>

这给了我一个按钮,在纯石灰绿色背景上有一个 png 图像。

My 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到别的东西?


唉,在 Windows 窗体中,它实际上就是一行。在 WPF 中,看起来会是几百个。

那是因为它是唯一可以放置在 winforms 按钮中的东西。 WPF 是一个真正的 UI 框架,而不是一些随机的半废弃的恐龙,只允许执行默认的操作(顺便说一句,这看起来很糟糕)。

选项 1:将图像放置为按钮的Content:

如果您只想在按钮中放置图像,而不是其他任何东西,为什么不这样做呢?

        <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>

Then:

     <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>

Result:

enter image description here

选项 2(不是很优雅):使用Tag财产:

如果除了图像之外,您还想在按钮中放入其他内容,则可以采用一种有点老套的方法,将 ImageSource 放入按钮中Tag财产。

        <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>

Then:

    <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>

Result:

enter image description here

选项 3:使用附属财产

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

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

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

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

选项 5:MVVM

创建一个ButtonViewModel,或者实际上使用委托命令在 ViewModel 中声明以绑定 Button 的属性。

不是一个选项:遍历可视化树并更改Image.Source在代码中。

这不是你想做的事情。这根本不是一个好方法。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以编程方式更改 WPF 按钮背景图像 的相关文章

  • 插入多重集中:在该值第一次出现之前而不是最后一次出现之后

    正如标题所示 multiset 在所有相同值的范围末尾插入一个值 例如 在多重集中插入 21 2 2 3做到了1 2 2 new 2 3 如何在所有相同值的范围开头插入新值 例如 在多重集中插入 21 2 2 3应该使1 new 2 2 2
  • OpenSSL:RSA 加密/解密、密钥生成和密钥持久性

    我正在尝试构建一个需要以下内容的 p2p 应用程序 在 OpenSSL 中使用 RSA Encryption Decryption Generating Keys done Saving and loading keys done Savi
  • 为什么纯虚拟析构函数的实现必须为空?它应该是内联的吗?

    我在其他线程中读到 当您实现纯虚拟析构函数 是的 它可以有一个实现 时 它必须是空的 并且应该 是内联的 应该是空的吗 如果是这样 为什么 应该内联吗 如果是这样 为什么 编辑 这就是纯虚拟析构函数的实现方式 class A virtual
  • 为什么这个 IA32 汇编代码有 3 个 leaal 指令?

    我编译了这个C函数 int calc int x int y int z return x 3 y 19 z 我在 calc s 中得到了这个 我正在注释正在发生的事情 file calc c text globl calc type ca
  • 寻求有关 cs50“现金”问题集的 C 贪婪算法的帮助[已关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 目标是创建一种算法 该算法接受输入并给出从输入中减去值 25 10 5 1 的次数的输出 代码需要以尽可能贪婪的方式执行此操作 尽可能获取最
  • 具有自动返回类型推导的 Friend 函数模板无法访问私有成员

    抱歉这个问题的标题太复杂了 我试图描述我为这个问题构建的最小 SSCCE 我有以下代码 include
  • asm、asm 易失性内存和破坏性内存之间的区别

    在实现无锁数据结构和定时代码时 通常需要抑制编译器的优化 通常人们使用asm volatile with memory在 clobber 列表中 但有时你会看到asm volatile或者只是一个简单的asm破坏记忆 这些不同的语句对代码生
  • 资源文件中的控制字符 C#

    我想添加Left To Right控制字符在resource resx文件输入Visual Studio 我在互联网上搜索并找到了一个名为在 NET 资源文件中转义序列的另一种方法 http www devx com tips Tip 34
  • Linq Any 始终返回 true

    我已经使用 Linq to Entities 多年 但这是我第一次遇到这个问题 我有Tips and Items表 每个提示可以有很多项目 我的数据库中只有 3 个项目 编辑项目时 我想确保GivenId对于具有相同提示的项目 字段是唯一的
  • 委托 System.Action 不接受 1 个参数

    那个行动 readonly Action execute public RelayCommand Action execute this execute null public RelayCommand Action execute Fun
  • 改装和授权标头

    目前 我正在向我的请求添加授权标头 如下所示 文件 SomeFile cs public interface ITestApi Get api test id Task
  • 如何使用 CMake 链接多个库

    我有一些与 DCMTK 相关的代码 如果我从命令行使用 g 我可以成功构建并运行它 这是代码 include dcmtk config osconfig h include dcmtk dcmdata dctk h int main Dcm
  • 减少最大值并保存其索引

    int v 10 2 9 1 3 5 7 1 2 0 0 int maximo 0 int b 0 int i pragma omp parallel for shared v private i reduction max maximo
  • 值类型数组如何存储在 .NET 对象堆中?

    在 NET中 诸如int之类的值类型对象存储在内存中 引用类型对象需要为引用和对象单独分配内存 并且对象存储在 NET对象堆中 而Array是在堆中创建的 那么int 等值类型的数组如何存储在堆中呢 这是否意味着值类型对象可以存储在堆中而无
  • C++ 访问嵌套类的私有成员

    标题可能有点误导 我有以下问题 我有一棵由叶子和内部节点组成的树 用户应该能够在叶子中存储任何信息and该树有一些方法可以获取一组用户定义的值 并且需要在恒定时间内 未摊销 访问相应的叶子 我提出了以下想法 但它不起作用 因为不幸的是我无法
  • 即使在不活动状态下,Hangfire 也会继续运行 SQL 查询

    我正在开发一个 ASP net MVC 5 网站 并使用 Hangfire 来安排一些任务 在本例中每 3 分钟一次 我知道一个事实是 运行这样的任务 以及与之相关的数据库查询 只需要几秒钟 我面临的问题是 Hangfire 似乎让我的 S
  • 在多个线程中添加和删除时 List 中的 null 值

    我知道 C System Collections Generic List 对象不是线程安全的 但我想知道为什么这段代码会生成空值 Task Run gt for var i 0 i lt 10 i var str Test i list
  • 如何根据条件退出 PostSharp 方面的 OnEntry 方法中的方法

    我希望方面根据如下条件退出方法调用 AttributeUsage AttributeTargets Method public class IgnoreIfInactiveAttribute OnMethodBoundaryAspect p
  • 对数据绑定组合框进行排序的最佳方法是什么?

    我对此做了一些研究 似乎对数据绑定组合框进行排序的唯一方法是对数据源本身进行排序 在本例中为数据集中的数据表 如果是这种情况 那么问题就变成对数据表进行排序的最佳方法是什么 组合框绑定在设计器中设置初始化使用 myCombo DataSou
  • 找出用户属于哪些组

    我有一个刚刚创建的 Windows 用户帐户 以 XYZ 为例 此 XYZ 属于我在计算机管理 gt 本地用户和组中创建的用户组和自定义组 因此 在属性中我看到该用户属于 2 个组 现在我想获取这些组并显示它们 有什么建议么 我已经这样做了

随机推荐

  • 在 PHP 中使用聚合方法和新的 MongoDB 驱动程序类

    我是蒙戈新手 我尝试获取文档的子文档 这是我的文档 id ObjectId 5900ab35c720b210c000032c name B 1 providers id ObjectId 59030550c720b211dc005e9e n
  • 在线性时间和常量空间中查找数组中缺失和重复的元素

    给你一个数组N64 位整数 N可能非常大 您知道每个整数 1 N 在数组中都会出现一次 除了有一个整数缺失和一个整数重复 编写一个线性时间算法来查找丢失和重复的数字 此外 您的算法应该在较小的恒定空间中运行 并且保持数组不变 Source
  • 如何使用 ggplot2 在一组美国县周围创建边界?

    我对使用 R 比较陌生 我正在尝试使用数据来创建美国各州的地图 以勾勒出某些区域的轮廓并为其着色 我正在尝试用黑色显示一个州及其县 除此之外 我想在县组周围创建粗红色边框 并根据我拥有的一些数据对一些县进行颜色填充 本质上我想结合这两个图像
  • 使用授权过滤器区分控制器操作

    我想要 4 个具有相同名称的操作 控制器方法可能有不同的名称 但它们的名称相同 ActionName 它们的属性对于所有 4 个都是相同的 ActionName Same name public ActionResult AnonActio
  • Swift:表视图超类错误

    我使用 Swift 创建了一个滑出菜单 我之前已经做过很多次了 但是当我今天创建它时 我收到了这个错误 参见屏幕截图 这可能只是我犯的一个简单错误 这是我认为导致问题的代码 override func tableView tableView
  • Laravel 4.2,Artisan::call() 忽略 --env 选项

    我正在构建一个应用程序 需要创建新数据库 执行迁移并通过网页播种数据库数据 我正在尝试使用 Laravel 4 2 中的以下代码来实现此目的 请注意 这是在我设置的控制器内 Artisan call migrate array env gt
  • GWT 动态区域设置

    我想设置gwt locale在 Spring 的帮助下获取用户选择的区域设置LocaleContextHolder public static final String getCurrentLocale return LocaleConte
  • 从 strings.xml 中的数组设置微调器的值

    我有一个微调器 它使用 strings xml 中的数组 如果数组有 5 个字符串 1 2 3 4 5 并且我希望微调器显示第二个 string 2 作为默认值 这可能吗 我知道我可以重新排列字符串顺序 使第一个字符串为 2 但如果旋转对话
  • 用于匹配空格或标点符号和非字母数字的正则表达式

    我有这个正则表达式 s 这与数组中的任何空格或标点符号匹配 但不是所有标点符号 我正在努力寻找与任何标点符号匹配的示例 我考虑过匹配字符不是字母数字的位置 但这会导致重音字母和不同词典的问题 是否有全包标点符号 例如 当我说标点符号时我希望
  • 使用 PyDev 出现错误: at 0x0000000002731828> [重复]

    这个问题在这里已经有答案了 我收到一个简单打印语句的错误 可能的错误是什么 已更改为浮动并尝试过 但错误仍然存 在 if name main print i i for i in range 5 error
  • Laravel 验证规则需要两个字段之一,但两个字段都不应该同时存在

    当需要两个字段中的任何一个但两个字段不应同时存在时 是否有 Laravel 验证规则 例如 手机号码和电子邮件 其中一个应该存在 但不能同时存在 不幸的是 我找不到一个 为了满足您的需求 以下是我采取的步骤 Laravel 对于制作一个的情
  • CommandParameter 与 ListView 命令绑定无关

    我没有成功从 ListView 项目发送 CommandParameter 我的代码如下
  • 第一次机会例外

    我一直在浏览 MSDN 帮助文档来掌握 Visual Basic 尝试使用计时器的示例后 将标签和计时器组件拖到设计器中 并将以下内容添加到组件子例程中 Label1 Text My Computer Clock LocalTime ToL
  • 用于多态/单表继承关联的 Rails 嵌套属性形式

    我正在开发一个表单 使用 SimpleForm 它允许您编辑嵌入的关联 我遇到的问题是嵌套模型是子类 因此它们是不同的类型 具有可能不同的字段 我正在为每种类型的模型创建隐藏表单 并使用 JavaScript 显示所选类型的表单 仅供参考
  • 向 Angular HttpClient 添加 HTTP 标头不会发送标头,为什么?

    这是我的代码 import HttpClient HttpErrorResponse HttpHeaders from angular common http logIn username string password string co
  • 使用 NumPy 将固定调色板应用于图像?

    我有一个 RGB 字节的 NumPy 图像 假设它是这个 2x3 图像 img np array 0 255 0 255 255 255 255 0 255 0 255 255 255 0 255 0 0 0 我还有一个调色板 涵盖图像中使
  • 如何使用JavaScript更新/更改HTML内容并防止页面刷新?

    我是脚本新手 我想用 JavaScript 更新 HTML 内容 但正如你所看到的 网页不断刷新 如何防止页面刷新 JavaScript function showResult form var coba form willbeshown
  • 如何将数组中的数字“加倍”,并将其保存在新数组中

    这是一个两步问题 1 我试图将一个数组 原始数组 的内容 加倍 将其保存在一个新数组 加倍数组 中 2 然后将这两个数组分配给具有 2 个属性的对象 新对象 原始号码 双数 这就是我到目前为止所拥有的 我做错了什么 var numbers
  • 如何使用数据字段获取组合框显示值?

    我已在资源编辑器中将组合框数据设置为 第一 第二 第三 但是当我编译程序时 组合框完全是空的 我根本看不到任何项目 另外 如何设置默认选择哪个项目 如何以编程方式更改当前选定的项目 答案可以在这篇文章中找到 http codeguru ea
  • 以编程方式更改 WPF 按钮背景图像

    我正在尝试创建一个