WPF动态加载XAML时引用本地自定义控件失败的解决方法
解决动态加载XAML引用主程序自定义控件的问题
1. 修正XAML中的命名空间声明
你的XAML仅指定了clr-namespace:Lemur.GUI,但动态解析时XamlReader无法自动关联到主程序集,必须明确添加程序集名称:
xmlns:local="clr-namespace:Lemur.GUI;assembly=你的主程序集名称"
获取程序集名称的方法:打开主项目属性→应用程序→程序集名称,直接使用该值即可。如果不想硬编码,也可以在代码中通过Assembly.GetExecutingAssembly().GetName().Name动态获取,再替换XAML里的命名空间字符串。
2. 给XamlReader指定解析上下文(更可靠的方案)
如果第一步仍无法解决问题,手动创建ParserContext,明确告知XamlReader自定义类型的位置。修改你的ParseUserControl方法:
public static UserControl? ParseUserControl(string xaml) { var task = Computer.Current.Window.Dispatcher.InvokeAsync(() => { try { var context = new ParserContext(); // 添加命名空间映射,替换为你的主程序集名称 context.XmlnsDictionary.Add("local", "clr-namespace:Lemur.GUI;assembly=你的主程序集名称"); // 也可以直接关联控件所在程序集,精度更高 // var controlAssembly = typeof(ResizableWindow).Assembly; // context.XamlTypeMapper = new XamlTypeMapper(new string[] { controlAssembly.FullName }); // context.XamlTypeMapper.AddMappingProcessingInstruction("local", "Lemur.GUI", controlAssembly.FullName); return XamlReader.Parse(xaml, context) as UserControl; } catch (XamlParseException ex) { Notifications.Now($"XAML parsing error: {ex.Message}"); } return null; }); task.Wait(); return task.Result; }
额外注意事项
- 确保
ResizableWindow是public类型:如果控件是internal修饰的,XamlReader动态解析时无法访问,必须改为public。 - 无需手动加载程序集到AppDomain:主程序集已在运行中,AppDomain内必然存在,问题根源是
XamlReader的解析上下文未关联到该程序集。
内容的提问来源于stack exchange,提问作者tool
相关产品推荐
相关产品推荐

