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
相关产品推荐
相关产品推荐

