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

UWP中ResourceDictionary自定义控件的SvgImageSource加载失败问题

UWP移植WinUI3控件时SVG图标加载空白问题

问题详情

正在将WinUI3库移植到UWP,自定义了public sealed class CustomButton : Button控件,包含Icon属性(类型为ImageSource)。控件UI通过ResourceDictionary定义,在App.xaml的MergedDictionaries中导入:

<CustomDictionary xmlns="using:CustomLibrary.UWP.UI" />

需求是为不同CustomButton样式设置不同SVG图标,同时允许用户自定义图标。在WinUI3中,会在ResourceDictionary的代码后置里通过以下代码将SVG转为SvgImageSource(因ResourceDictionary无法使用x:Bind):

((Style)this["DefaultCustomButtonStyle"]).Setters.Add(new Setter(CustomButton.IconProperty, Icons.ToImageSource(Icons.Default)));

但在UWP中,图片显示空白——调试发现图片已创建且尺寸正确,但内容为空。Icons.ToImageSource函数单独测试正常,直接给Image的Source赋值能正常显示SVG。

奇怪的是:在App.xaml中导入字典就会出问题,在使用CustomButton的视图内导入字典则一切正常。

原因分析

UWP中App.xaml的ResourceDictionary加载时机早于控件初始化,此时SvgImageSource的异步加载逻辑可能还未完成,或者资源上下文存在差异,导致SVG内容无法正确渲染到Style的Setter中。而在视图内导入字典时,视图加载时机更晚,控件上下文已就绪,SVG加载逻辑能正常执行。

解决方案

方案1:延迟图标赋值到控件加载时

不在ResourceDictionary的构造函数或Loaded事件中直接设置Setter,而是在CustomButton的首次加载事件中处理图标赋值,仅当用户未自定义Icon且使用默认样式时自动赋值:

public sealed class CustomButton : Button
{
    public static readonly DependencyProperty IconProperty =
        DependencyProperty.Register(nameof(Icon), typeof(ImageSource), typeof(CustomButton), new PropertyMetadata(null));

    public ImageSource Icon
    {
        get => (ImageSource)GetValue(IconProperty);
        set => SetValue(IconProperty, value);
    }

    protected override void OnLoaded(object sender, RoutedEventArgs e)
    {
        base.OnLoaded(sender, e);
        // 仅当未自定义Icon且使用默认样式时赋值
        if (Icon == null && Style?.Key is string key && key == "DefaultCustomButtonStyle")
        {
            Icon = Icons.ToImageSource(Icons.Default);
        }
    }
}

方案2:在ResourceDictionary模板应用后设置Setter

若坚持在ResourceDictionary中处理,可重写OnApplyTemplate方法,确保控件模板应用完成后再添加Setter:

public sealed partial class CustomDictionary : ResourceDictionary
{
    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        if (TryGetValue("DefaultCustomButtonStyle", out object styleObj) && styleObj is Style style)
        {
            style.Setters.Add(new Setter(CustomButton.IconProperty, Icons.ToImageSource(Icons.Default)));
        }
    }
}

方案3:直接引用嵌入式SVG资源

把SVG文件作为嵌入式资源,在XAML中直接通过SvgImageSource的Uri引用,绕开代码后置的时机问题:

<Style x:Key="DefaultCustomButtonStyle" TargetType="local:CustomButton">
    <Setter Property="Icon" Value="ms-appx:///CustomLibrary.UWP/Assets/DefaultIcon.svg" />
</Style>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 22:47:23