WPF中复用Visual Studio 2022 XAML图标遇问题及解决方法
解决WPF中复用Visual Studio 2022图标资源时的消失问题
我在ResourceDictionary中使用Visual Studio 2022 Image Library提供的XAML格式图标,原本通过指定Key就能将其作为WPF控件的内容使用,示例代码如下:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Rectangle x:Key="ProcessIcon" Width="16 " Height="16"> <Rectangle.Resources> <SolidColorBrush x:Key="canvas" Opacity="0" /> <SolidColorBrush x:Key="light-defaultgrey" Color="#212121" Opacity="1" /> </Rectangle.Resources> <Rectangle.Fill> <DrawingBrush Stretch="None"> <DrawingBrush.Drawing> <DrawingGroup> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource canvas}" Geometry="F1M16,16H0V0H16Z" /> </DrawingGroup> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource light-defaultgrey}" Geometry="F1M8,5V4H6.949a2.473,2.473,0,0,0-.365-.876l.745-.745-.707-.707-.745.745A2.469,2.469,0,0,0,5,2.051V1H4V2.051a2.469,2.469,0,0,0-.877.366l-.745-.745-.707.707.745.745A2.473,2.473,0,0,0,2.051,4H1V5H2.051a2.473,2.473,0,0,0,.365.876l-.745.745.707.707.745-.745A2.469,2.469,0,0,0,4,6.949V8H5V6.949a2.469,2.469,0,0,0,.877-.366l.745.745.707-.707-.745-.745A2.473,2.473,0,0,0,6.949,5ZM4.5,6A1.5,1.5,0,1,1,6,4.5,1.5,1.5,0,0,1,4.5,6Z" /> <GeometryDrawing Brush="{DynamicResource light-defaultgrey}" Geometry="F1M13.937,10.633a3.271,3.271,0,0,0-.1-.784l1.242-.514-.383-.924-1.244.515A3.314,3.314,0,0,0,12.34,7.819l.515-1.245-.923-.383-.515,1.242a3.007,3.007,0,0,0-1.568,0L9.335,6.191l-.924.383.515,1.245A3.311,3.311,0,0,0,7.819,8.926L6.575,8.411l-.383.924,1.241.514a3.007,3.007,0,0,0,0,1.568l-1.241.515.383.923,1.244-.515a3.314,3.314,0,0,0,1.107,1.108l-.515,1.243.924.383.514-1.241a2.983,2.983,0,0,0,1.569,0l.514,1.241.923-.383-.515-1.243a3.307,3.307,0,0,0,1.108-1.108l1.244.515.383-.923-1.242-.515A3.278,3.278,0,0,0,13.937,10.633Zm-5.608,0a2.3,2.3,0,1,1,2.3,2.305A2.307,2.307,0,0,1,8.329,10.633Z" /> </DrawingGroup> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Fill> </Rectangle> </ResourceDictionary>
使用时的按钮代码:
<Button Command="{Binding ...}"> <StackPanel Orientation="Horizontal"> <Label Content="{StaticResource ProcessIcon}" Margin="0 -5"/> <TextBlock Text="Title" /> </StackPanel> </Button>
但这种方式只能支持单个按钮使用,当在第二个按钮中复用同一图标时,第一个按钮上的图标会消失。
问题原因
经排查,问题出在该图标是FrameworkElement类型(此处为Rectangle),而WPF中FrameworkElement只能拥有一个父元素。理论上可以通过设置x:Shared=False来解决,但该方法未生效,推测可能和ResourceDictionary的特性或图标并非图片类型有关。同时也不清楚如何将Rectangle转换为图片格式,毕竟这些XAML代码来自微软官方包。
解决方案
基于emoacht的思路,我通过以下方式实现了图标复用:
首先修改ResourceDictionary,将原来的Rectangle资源包装为VisualBrush:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <VisualBrush x:Key="ProcessIcon"> <VisualBrush.Visual> <Rectangle Width="16 " Height="16"> <Rectangle.Resources> <SolidColorBrush x:Key="canvas" Opacity="0" /> <SolidColorBrush x:Key="light-defaultgrey" Color="#212121" Opacity="1" /> </Rectangle.Resources> <Rectangle.Fill> <DrawingBrush Stretch="None"> <DrawingBrush.Drawing> <DrawingGroup> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource canvas}" Geometry="F1M16,16H0V0H16Z" /> </DrawingGroup> <DrawingGroup> <GeometryDrawing Brush="{DynamicResource light-defaultgrey}" Geometry="F1M8,5V4H6.949a2.473,2.473,0,0,0-.365-.876l.745-.745-.707-.707-.745.745A2.469,2.469,0,0,0,5,2.051V1H4V2.051a2.469,2.469,0,0,0-.877.366l-.745-.745-.707.707.745.745A2.473,2.473,0,0,0,2.051,4H1V5H2.051a2.473,2.473,0,0,0,.365.876l-.745.745.707.707.745-.745A2.469,2.469,0,0,0,4,6.949V8H5V6.949a2.469,2.469,0,0,0,.877-.366l.745.745.707-.707-.745-.745A2.473,2.473,0,0,0,6.949,5ZM4.5,6A1.5,1.5,0,1,1,6,4.5,1.5,1.5,0,0,1,4.5,6Z" /> <GeometryDrawing Brush="{DynamicResource light-defaultgrey}" Geometry="F1M13.937,10.633a3.271,3.271,0,0,0-.1-.784l1.242-.514-.383-.924-1.244.515A3.314,3.314,0,0,0,12.34,7.819l.515-1.245-.923-.383-.515,1.242a3.007,3.007,0,0,0-1.568,0L9.335,6.191l-.924.383.515,1.245A3.311,3.311,0,0,0,7.819,8.926L6.575,8.411l-.383.924,1.241.514a3.007,3.007,0,0,0,0,1.568l-1.241.515.383.923,1.244-.515a3.314,3.314,0,0,0,1.107,1.108l-.515,1.243.924.383.514-1.241a2.983,2.983,0,0,0,1.569,0l.514,1.241.923-.383-.515-1.243a3.307,3.307,0,0,0,1.108-1.108l1.244.515.383-.923-1.242-.515A3.278,3.278,0,0,0,13.937,10.633Zm-5.608,0a2.3,2.3,0,1,1,2.3,2.305A2.307,2.307,0,0,1,8.329,10.633Z" /> </DrawingGroup> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Fill> </Rectangle> </VisualBrush.Visual> </VisualBrush> </ResourceDictionary>
然后修改按钮的使用方式,将图标作为Label的Background而非Content:
<Button Command="{Binding ...}"> <StackPanel Orientation="Horizontal"> <Label Background="{StaticResource ProcessIcon}" Width="16" Height="16" Margin="5 0" /> <TextBlock Text="Title" /> </StackPanel> </Button>
这样修改后,同一个图标资源就可以在多个按钮中复用,不会出现图标消失的问题。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

