C# WPF 按钮加载系统图标 / 动物头像

C# WPF 按钮加载系统图标 / 动物头像

重点:Windows系统DLL里没有动物头像 ,动物图片需要自己准备PNG/ICO。WPF没有Image属性,按钮内部放Image控件实现图文按钮;WPF原生没有Icon→BitmapSource,需要P/Invoke把HICON转WPF的ImageSource。

方式1:Segoe MDL2 / Fluent 系统字体图标(最简单,推荐)

Windows自带字体图标,不用DLL提取,XAML直接写在Button内,无GDI资源泄漏。

复制代码
<Button Width="140" Height="40">
    <StackPanel Orientation="Horizontal">
        <!-- Segoe MDL2 Assets 系统图标,Windows10自带 -->
        <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="20" Text="&#xE78B;" Foreground="Black"/>
        <TextBlock Text=" 文件夹" VerticalAlignment="Center"/>
    </StackPanel>
</Button>

常用glyph:

  • &#xE78B; 文件夹
  • &#xE700; 主页
  • &#xE71D; 警告
  • &#xE72E; 信息

Win11:Segoe Fluent Icons,图标编码不一样。

方式2:从 imageres.dll / shell32.dll 提取系统图标(PInvoke)

完整辅助类 IconHelper.cs

复制代码
using System;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows.Media.Imaging;

public static class IconHelper
{
    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    private static extern int ExtractIconEx(string lpszFile, int nIconIndex, out IntPtr phIconLarge, out IntPtr phIconSmall, int nIcons);

    [DllImport("user32.dll")]
    private static extern bool DestroyIcon(IntPtr hIcon);

    /// <summary>从DLL提取图标,转为WPF可用ImageSource</summary>
    public static BitmapSource? GetIconFromDll(string dllPath, int iconIndex)
    {
        IntPtr hLarge, hSmall;
        int ret = ExtractIconEx(dllPath, iconIndex, out hLarge, out hSmall, 1);
        if (ret <= 0 || hLarge == IntPtr.Zero) return null;

        BitmapSource bitmapSource = Imaging.CreateBitmapSourceFromHIcon(hLarge, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        DestroyIcon(hLarge);
        DestroyIcon(hSmall);
        return bitmapSource;
    }
}

XAML按钮

复制代码
<Button x:Name="btnFolder" Width="140" Height="40">
    <StackPanel Orientation="Horizontal">
        <Image x:Name="imgIcon" Width="24" Height="24"/>
        <TextBlock Text="文件夹按钮" Margin="5,0"/>
    </StackPanel>
</Button>

后台C#加载

复制代码
using System.IO;

public MainWindow()
{
    InitializeComponent();
    string dll = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), @"System32\imageres.dll");
    imgIcon.Source = IconHelper.GetIconFromDll(dll, 3); // index=3 文件夹图标
}

方式3:动物头像(本地图片/项目资源)

① 把图片加入项目资源

  1. 把cat.png放到项目,属性设置:生成操作 = 资源

  2. XAML直接写按钮:

② C#代码动态加载本地动物图片

复制代码
var uri = new Uri(@"C:\Pics\cat.png", UriKind.Absolute);
imgIcon.Source = new BitmapImage(uri);

封装成通用图文Button模板(推荐复用)

复制代码
<Window.Resources>
    <Style x:Key="IconButtonStyle" TargetType="Button">
        <Setter Property="Width" Value="140"/>
        <Setter Property="Height" Value="40"/>
        <Setter Property="Content">
            <Setter.Value>
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="imgBtn" Width="22" Height="22"/>
                    <TextBlock x:Name="txtBtn" Margin="6,0" VerticalAlignment="Center"/>
                </StackPanel>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Button Style="{StaticResource IconButtonStyle}" x:Name="btnAnimal"/>

重要坑点

  1. Win10 1903+ :很多系统图标迁移到 shell32.dll.mun,ExtractIconEx读取mun会失败,优先用Segoe字体图标更稳。
  2. 不要混用System.Drawing.Icon长期持有,WPF用Imaging.CreateBitmapSourceFromHIcon并且必须DestroyIcon释放句柄,否则内存泄漏。
  3. 32位程序在64位系统会被重定向到SysWOW64,读取imageres.dll会拿到旧版本图标,项目平台设为x64。
  4. 动物头像:Windows没有内置动物图标,只能自己准备PNG图片。

扩展:获取系统内置标准图标(Error/Warning/Info)

复制代码
// 需要引用 System.Drawing.Common
using System.Drawing;

public static BitmapSource GetSysIcon(System.Drawing.Icon icon)
{
    return Imaging.CreateBitmapSourceFromHIcon(icon.Handle, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}

// 调用
imgIcon.Source = GetSysIcon(SystemIcons.Warning);

.NET6+ WPF需要手动NuGet安装 System.Drawing.Common

需要我给你一份Segoe MDL2常用图标清单,或者写一个弹窗预览imageres全部图标吗?

相关推荐
周杰伦fans1 天前
8GB显存下模型量化实战指南
人工智能·后端·c#
samble1 天前
从零搭建灌装监控系统(十二):配置系统,原子写入与容错
c#·wpf·mvvm·modbus·工业控制
流形填表1 天前
题库去重实战:基于题干指纹的重复题清理
开发语言·c#
开开心心就好1 天前
以图搜图找重复图片,本地工具离线就能用
javascript·智能手机·ffmpeg·c#·ocr·word·音视频
CSharp精选营2 天前
.NET 面试必问的 8 道 GC 题,建议收藏
.net·面试题·gc·c#面试题
QQ_21696290962 天前
基于C#(Asp.net)电竞陪玩信息管理系统的设计与实现
java·大数据·spring boot·微信小程序·c#·云计算·asp.net
未来之窗软件服务2 天前
C# 截图源码支持自动保存-东方仙盟
c#·仙盟创梦ide·东方仙盟·电脑工具
UIU1142 天前
-7 / 2 在 C 里是 -3,在 Python 里是 -4,谁算错了?
c++·学习·c#
wflynn2 天前
GitHub 今日推荐|REDox:64 位 token 表示结构化数据,内存占用降 70% 支持多格式互转
开源·c#·github
驰骋工作流3 天前
C#/.NET 开源BPM工作流引擎6大常用对比选型分析驰骋BPM驰骋低代码低代码工作流引擎
开源·c#·.net