通过代码修改Application.Current.Resources触发COM异常问题求助
这个错误我之前在WPF项目里踩过坑,核心原因很明确:你试图修改的资源来自一个设置了Source属性的资源字典(比如系统自带的主题字典,或是你通过外部XAML文件引用的字典),这类字典是只读的,不允许直接通过代码设置本地值覆盖原有项。不管是系统预定义的ListViewItemBackgroundSelected还是你自己放在外部字典里的自定义资源,只要字典是通过Source加载的,就会触发这个错误。
下面给你几个可行的解决方案:
1. 通过合并字典覆盖资源(推荐用于系统/外部字典资源)
与其直接修改只读字典里的项,不如创建一个自定义资源字典,把需要修改的资源键重新定义一遍,然后将这个字典添加到Application.Current.Resources.MergedDictionaries中。因为合并字典的优先级高于原有字典,新定义的资源会自动覆盖旧值。
代码示例:
// 创建自定义资源字典 var overrideDict = new ResourceDictionary(); // 重新定义需要修改的资源键 overrideDict["ListViewItemBackgroundSelected"] = new SolidColorBrush(Colors.Black); // 添加到应用的合并字典集合 Application.Current.Resources.MergedDictionaries.Add(overrideDict);
如果是XAML里操作,也可以直接在App.xaml中添加合并字典:
<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- 系统默认主题字典 --> <ResourceDictionary Source="PresentationFramework.Aero2;component/themes/Aero2.NormalColor.xaml"/> <!-- 自定义覆盖字典 --> <ResourceDictionary Source="CustomOverrides.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
在CustomOverrides.xaml里定义你要修改的资源即可。
2. 确保资源在本地字典中定义(适用于自定义资源)
如果是你自己的自定义资源,不要把它放在带Source的外部字典里,而是直接在Application.Resources中定义本地资源,这样就能直接通过代码修改了。
比如在App.xaml中定义:
<Application.Resources> <SolidColorBrush x:Key="MyCustomBackground" Color="LightBlue"/> </Application.Resources>
然后代码里修改就不会报错了:
Application.Current.Resources["MyCustomBackground"] = new SolidColorBrush(Colors.DarkBlue);
为什么原来的代码会报错?
系统主题字典(比如PresentationFramework.Aero2.dll中的资源)是通过Source属性加载的,这类字典在加载时会被标记为“不可修改”,本质是因为它们属于外部程序集的资源,WPF不允许直接修改这类只读字典的条目,只能通过优先级更高的合并字典来覆盖。
内容的提问来源于stack exchange,提问作者ac-lap

