You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI 3:动态加载的SVG图标无法正确渲染的原因

动态加载SVG到NavigationViewItem图标不渲染的问题排查与解决

问题概述

在构建包含静态和动态菜单项的NavigationView时,静态菜单项通过URI加载SVG图标可正常显示,但动态通过流加载SVG图标的菜单项无法正确渲染图标。

静态XAML代码:

<NavigationViewItem Content="Static item">
    <NavigationViewItem.Icon>
        <ImageIcon Source="/Assets/Android_Jelly_Bean_Logo.svg"/>
    </NavigationViewItem.Icon>
</NavigationViewItem>

动态C#代码(原版本):

private async void _addNavigationItem()
{
    var svgCode = "<my svg code string>";

    var svgSource = new SvgImageSource();
    var imageIcon = new ImageIcon();
    imageIcon.Source = svgSource;
    var svgBuffer = CryptographicBuffer.ConvertStringToBinary(svgCode, BinaryStringEncoding.Utf8);

    using (var stream = svgBuffer.AsStream())
    {
       await svgSource.SetSourceAsync(stream.AsRandomAccessStream());
    }

    var item = new NavigationViewItem() {
        Content = "hello",
        Icon = imageIcon
    };

    NavigationViewControl.MenuItems.Add(item);
}

可能的原因及解决方法

1. SVG代码无效或不完整

原代码中svgCode为占位符,必须确保使用完整、有效的SVG内容。可通过HttpClient获取目标SVG的内容:

private async Task<string> GetSvgContentAsync()
{
    using var client = new HttpClient();
    return await client.GetStringAsync("https://upload.wikimedia.org/wikipedia/commons/7/7a/Android_Jelly_Bean_Logo.svg");
}

2. 流位置未重置

字符串转流后,流的默认位置处于末尾,导致SetSourceAsync无法读取内容。需在使用前重置流位置到开头:

using (var stream = svgBuffer.AsStream())
{
    stream.Position = 0; // 重置流位置
    await svgSource.SetSourceAsync(stream.AsRandomAccessStream());
}

3. Async void方法的潜在问题

async void方法无法被正确等待,且异常会直接抛出到调用上下文,建议改为async Task并在调用时使用await:

private async Task AddNavigationItemAsync()
{
    // 原逻辑...
}

// 调用示例
await AddNavigationItemAsync();

4. SVG尺寸未适配NavigationView图标大小

NavigationView图标有固定尺寸(通常为24x24),若SVG未设置width和height属性,可能导致渲染异常。可手动设置SvgImageSource的解码尺寸:

var svgSource = new SvgImageSource()
{
    DecodePixelWidth = 24,
    DecodePixelHeight = 24
};

修正后的完整代码

private async Task AddNavigationItemAsync()
{
    // 获取有效的SVG内容
    using var client = new HttpClient();
    var svgCode = await client.GetStringAsync("https://upload.wikimedia.org/wikipedia/commons/7/7a/Android_Jelly_Bean_Logo.svg");

    var svgSource = new SvgImageSource()
    {
        DecodePixelWidth = 24,
        DecodePixelHeight = 24
    };
    var imageIcon = new ImageIcon();
    imageIcon.Source = svgSource;

    var svgBuffer = CryptographicBuffer.ConvertStringToBinary(svgCode, BinaryStringEncoding.Utf8);
    using (var stream = svgBuffer.AsStream())
    {
        stream.Position = 0;
        await svgSource.SetSourceAsync(stream.AsRandomAccessStream());
    }

    var item = new NavigationViewItem()
    {
        Content = "hello",
        Icon = imageIcon
    };

    NavigationViewControl.MenuItems.Add(item);
}

内容的提问来源于stack exchange,提问作者Daniele Pugliese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:46:09