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

修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 00:15:29