修改DynamicResource后WPF图标颜色未变更,如何实现运行时改色?
运行时修改WPF DrawingImage图标的颜色问题
问题描述
我定义了如下图标(XAML已简化,实际嵌套的DrawingGroup数量更多):
<DrawingImage x:Key="CloseIcon"> <DrawingImage.Drawing> <DrawingGroup ClipGeometry="M0,0 V27 H28 V0 H0 Z"> <DrawingGroup.Transform> <TranslateTransform X="3.9828000068664551" Y="0" /> </DrawingGroup.Transform> <DrawingGroup Opacity="1" Transform="1,0,0,1,0.885057,0.5"> <DrawingGroup Opacity="1" Transform="..."> <GeometryDrawing Brush="{DynamicResource PrimaryBrush}" Geometry="..." /> </DrawingGroup> <DrawingGroup Transform="..."> <GeometryDrawing Brush="{DynamicResource PrimaryBrush}" Geometry="..." /> </DrawingGroup> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage>
- 该图标定义在
IconResourcs.xaml文件中,通过ResourceDictionary.MergedDictionaries被包含在程序启动时加载的程序集Resources.xaml里。 - 程序加载时已设置
PrimaryBrush资源,之后运行时执行以下代码尝试修改图标颜色:
Application.Current.Resources["PrimaryBrush"] = new SolidColorBrush(Colors.Green);
但图标颜色并未改变,明明用了DynamicResource却没触发更新,求可行的解决方法。
解决方法
方法1:用绑定替代DynamicResource
GeometryDrawing不属于FrameworkElement,不支持DynamicResource的自动更新机制。把XAML中的{DynamicResource PrimaryBrush}替换为绑定表达式:
{Binding Source={x:Static Application.Current}, Path=Resources[PrimaryBrush]}
这样当Application.Current.Resources["PrimaryBrush"]更新时,绑定会自动刷新Brush的值,图标颜色随之变化。
方法2:手动遍历DrawingGroup更新Brush
如果要保留现有资源结构,可以在修改资源后,递归遍历DrawingImage里的所有GeometryDrawing,手动替换Brush:
private void UpdateIconBrush(Drawing drawing, Brush newBrush) { if (drawing is DrawingGroup group) { foreach (var childDrawing in group.Children) { UpdateIconBrush(childDrawing, newBrush); } } else if (drawing is GeometryDrawing geometryDrawing) { geometryDrawing.Brush = newBrush; } } // 调用示例 var closeIcon = Application.Current.Resources["CloseIcon"] as DrawingImage; if (closeIcon != null) { var greenBrush = new SolidColorBrush(Colors.Green); UpdateIconBrush(closeIcon.Drawing, greenBrush); // 重新赋值资源,触发UI更新 Application.Current.Resources["CloseIcon"] = closeIcon; }
方法3:用Style包装图标(推荐)
把图标放到Style中,让Image这类FrameworkElement来承载动态资源,这样DynamicResource就能正常工作:
<Style x:Key="CloseIconStyle" TargetType="Image"> <Setter Property="Source"> <Setter.Value> <DrawingImage> <DrawingImage.Drawing> <DrawingGroup ClipGeometry="M0,0 V27 H28 V0 H0 Z"> <DrawingGroup.Transform> <TranslateTransform X="3.9828000068664551" Y="0" /> </DrawingGroup.Transform> <DrawingGroup Opacity="1" Transform="1,0,0,1,0.885057,0.5"> <DrawingGroup Opacity="1" Transform="..."> <GeometryDrawing Brush="{DynamicResource PrimaryBrush}" Geometry="..." /> </DrawingGroup> <DrawingGroup Transform="..."> <GeometryDrawing Brush="{DynamicResource PrimaryBrush}" Geometry="..." /> </DrawingGroup> </DrawingGroup> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Setter.Value> </Setter> </Style>
使用时给Image应用该Style:
<Image Style="{StaticResource CloseIconStyle}" />
此时修改PrimaryBrush资源,图标颜色会自动更新,因为Image是FrameworkElement,完全支持DynamicResource的动态更新逻辑。
内容的提问来源于stack exchange,提问作者funkymushroom
相关产品推荐
相关产品推荐

