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

WinUI3中CommunityToolkit的BitmapIconExtension能否结合ThemeResource使用?

问题

我在WinUI 3中有如下可正常运行的XAML代码:

<ctc:SettingsCard Header="Directory">
    <ctc:SettingsCard.HeaderIcon>
        <BitmapIcon ShowAsMonochrome="False" UriSource="{ThemeResource DirectoryIcon}"/>
    </ctc:SettingsCard.HeaderIcon>
</ctc:SettingsCard>

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
         <x:String x:Key="DirectoryIcon">/Assets/DirectoryIconLight.png</x:String>
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
         <x:String x:Key="DirectoryIcon">/Assets/DirectoryIconDark.png</x:String>
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

CommunityToolkit.WinUI提供了BitmapIconExtension,官方示例代码如下:

<MenuFlyout xmlns:ui="using:CommunityToolkit.WinUI">

    <!--Before-->
    <MenuFlyoutItem Text="Click me!">
        <MenuFlyoutItem.Icon>
            <BitmapIcon Source="/Assets/myicon.png"/>
        </MenuFlyoutItem.Icon>
    </MenuFlyoutItem>

    <!--After-->
    <MenuFlyoutItem
        Text="No, click me!"
        Icon="{ui:BitmapIcon Source=/Assets/myicon.png}" />
</MenuFlyout>

于是我尝试用标记扩展简化写法,代码如下:

<ctc:SettingsCard Header="Directory" HeaderIcon="{ui:BitmapIcon Source={ThemeResource DirectoryIcon},ShowAsMonochrome=False}"/>

但运行报错:

Microsoft.UI.Xaml.Markup.XamlParseException: 'The text associated with this error code could not be found.

Failed to assign to property 'CommunityToolkit.WinUI.BitmapIconExtension.Source'. [Line: 142 Position: 39]'

请问是否可以将该标记扩展与ResourceDictionary中的Static/Theme资源一起使用?


解决方案

可以将BitmapIconExtension和主题资源配合使用,但XAML不支持在标记扩展的属性值里直接嵌套另一个标记扩展(比如{ThemeResource}不能直接写在{ui:BitmapIcon Source=...}的Source值里),这是导致报错的核心原因。

下面提供两种可行的实现方式:

方式一:在资源字典中定义完整的BitmapIcon实例

直接在主题资源字典里定义对应模式的BitmapIcon,而非仅存放图片路径,这样就能直接通过资源引用实现需求:

<ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
         <BitmapIcon x:Key="DirectoryBitmapIcon" ShowAsMonochrome="False" UriSource="/Assets/DirectoryIconLight.png"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
         <BitmapIcon x:Key="DirectoryBitmapIcon" ShowAsMonochrome="False" UriSource="/Assets/DirectoryIconDark.png"/>
    </ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>

之后在SettingsCard中直接引用该资源:

<ctc:SettingsCard Header="Directory" HeaderIcon="{ThemeResource DirectoryBitmapIcon}"/>

方式二:借助绑定传递主题资源路径

如果不想修改现有资源字典结构,可以通过绑定来传递主题资源的路径值,写法如下:

<ctc:SettingsCard Header="Directory">
    <ctc:SettingsCard.HeaderIcon>
        <ui:BitmapIconExtension>
            <ui:BitmapIconExtension.Source>
                <Binding Source="{ThemeResource DirectoryIcon}"/>
            </ui:BitmapIconExtension.Source>
            <ui:BitmapIconExtension.ShowAsMonochrome>False</ui:BitmapIconExtension.ShowAsMonochrome>
        </ui:BitmapIconExtension>
    </ctc:SettingsCard.HeaderIcon>
</ctc:SettingsCard>

不过这种写法和原有的显式声明BitmapIcon差异不大,若追求简洁性,更推荐方式一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 12:47:05