WPF跨项目引用DrawingGroup动态颜色失效问题求助
问题原因
资源字典中的DrawingGroup默认是共享实例(x:Shared="True"为默认值),且作为Freezable类型会被自动冻结。冻结后的对象无法响应DynamicResource的资源变更通知,因此修改IconAccentBrush时,跨项目引用的DrawingGroup不会更新颜色。而内联的DrawingGroup属于控件树的一部分,不会被自动冻结,所以能正常响应资源变化。
解决方案
以下是几种可行的解决方法:
方法1:给资源字典中的DrawingGroup设置x:Shared="False"
修改ImageDictionary.xaml,为DrawingGroup添加x:Shared="False"属性,让每个控件引用时生成独立实例,避免被冻结,从而响应DynamicResource的变更:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- 添加x:Shared="False"生成独立实例 --> <DrawingGroup x:Key="PushPinActiveDrawingGroup" x:Shared="False" ClipGeometry="M-19,1 V512.9995 H492 V-19 H1 Z"> <DrawingGroup.Transform> <TranslateTransform X="19" Y="-0.00097703933715820313" /> </DrawingGroup.Transform> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry1}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry2}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry3}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry4}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry5}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry6}" /> </DrawingGroup> </ResourceDictionary>
ToggleButton代码保持不变即可。
方法2:在资源字典中定义DrawingImage并设置x:Shared="False"
直接将DrawingImage放入资源字典,设置x:Shared="False"确保每个引用都是独立实例:
<!-- ImageDictionary.xaml --> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <DrawingImage x:Key="PushPinActiveImage" x:Shared="False"> <DrawingImage.Drawing> <DrawingGroup ClipGeometry="M-19,1 V512.9995 H492 V-19 H1 Z"> <DrawingGroup.Transform> <TranslateTransform X="19" Y="-0.00097703933715820313" /> </DrawingGroup.Transform> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry1}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry2}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry3}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry4}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry5}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry6}" /> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </ResourceDictionary>
然后在ToggleButton中直接引用:
<ToggleButton Margin="{StaticResource MainThickness}" IsChecked="{Binding IsPinned}"> <Image Source="{DynamicResource PushPinActiveImage}" /> </ToggleButton>
方法3:使用Style创建独立的DrawingImage实例
通过Style为每个ToggleButton生成独立的DrawingImage实例:
<!-- 在资源字典中添加Style --> <Style x:Key="PushPinToggleButtonStyle" TargetType="ToggleButton"> <Setter Property="Content"> <Setter.Value> <Image> <Image.Source> <DrawingImage> <DrawingImage.Drawing> <DrawingGroup ClipGeometry="M-19,1 V512.9995 H492 V-19 H1 Z"> <DrawingGroup.Transform> <TranslateTransform X="19" Y="-0.00097703933715820313" /> </DrawingGroup.Transform> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry1}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry2}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry3}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry4}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry5}" /> <GeometryDrawing Brush="{DynamicResource IconAccentBrush}" Geometry="{StaticResource ApplyColorGeometry6}" /> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> </Setter.Value> </Setter> </Style>
在ToggleButton中应用Style:
<ToggleButton Margin="{StaticResource MainThickness}" IsChecked="{Binding IsPinned}" Style="{StaticResource PushPinToggleButtonStyle}" />
内容的提问来源于stack exchange,提问作者Olivier La Haye
相关产品推荐
相关产品推荐

