WPF条件编译实现动态资源字典加载问题求助
动态加载WPF基础程序集资源字典的可行方案
方案1:通过程序集内标记类型动态构建URI
在基础程序集中定义一个空的标记类(比如ResourceAssemblyMarker),用于定位程序集,彻底避免硬编码程序集名称。然后在依赖的UserControl后台代码中,通过该类型获取程序集信息,动态生成资源字典的URI:
// 基础程序集内的标记类(可放在任意命名空间下) public class ResourceAssemblyMarker { } // 依赖UserControl的后台加载代码 var assembly = typeof(ResourceAssemblyMarker).Assembly; var resourceUri = new Uri($"/{assembly.GetName().Name};component/Resources.xaml", UriKind.Relative); var resDict = new ResourceDictionary { Source = resourceUri }; this.Resources.MergedDictionaries.Add(resDict);
这种方式完全不受程序集名称变更影响,只要标记类还在目标程序集内,就能正确定位资源。
方案2:直接通过程序集加载嵌入式资源
如果资源字典被标记为嵌入式资源(在VS属性窗口设置“生成操作”为“嵌入式资源”),可以用Application.LoadComponent直接加载,无需拼接URI:
var assembly = typeof(ResourceAssemblyMarker).Assembly; // 资源路径格式:[程序集默认命名空间].[资源所在文件夹路径].Resources.xaml var resourcePath = "YourBaseAssemblyNamespace.Resources.Resources.xaml"; var resDict = (ResourceDictionary)Application.LoadComponent( new Uri($"pack://application:,,,/{assembly.GetName().Name};component/{resourcePath}", UriKind.Absolute) ); this.Resources.MergedDictionaries.Add(resDict);
注意:资源路径需要和文件在项目中的结构对应,比如Resources文件夹下的Resources.xaml,路径就是命名空间.Resources.Resources.xaml。
方案3:修正条件编译的URI格式
如果必须保留条件编译的方式,之前的代码失败大概率是因为相对URI解析问题,改用完整的pack绝对路径格式,并确保编译常量正确配置:
首先在项目属性中定义编译常量(比如ASSEMBLY_NAME_A、ASSEMBLY_NAME_B),然后在代码中使用:
ResourceDictionary res = new(); #if ASSEMBLY_NAME_A res.Source = new Uri("pack://application:,,,/AssemblyNameA;component/Resources.xaml", UriKind.Absolute); #elif ASSEMBLY_NAME_B res.Source = new Uri("pack://application:,,,/AssemblyNameB;component/Resources.xaml", UriKind.Absolute); #endif this.Resources.MergedDictionaries.Add(res);
内容的提问来源于stack exchange,提问作者Cédrick Rauzy
相关产品推荐
相关产品推荐

