WPF使用Xaml.Parse解析含自定义控件的Xaml文件时触发XamlParseException
运行时解析外部XAML遇到XamlParseException问题
异常信息
System.Windows.Markup.XamlParseException:无法从local:DemoElement创建TargetType。
外部XAML文件(ExternalFile.xaml)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:StyleDemo"> <Style TargetType="local:DemoElement"> <Style.Resources> <!--<Style TargetType="Button">--> <Style TargetType="{x:Type Button}"> <Style.Triggers> <Trigger Property="Name" Value="Btn1"> <Setter Property="Background" Value="Green"/> <Setter Property="Margin" Value="100, 100, 0, 0"/> <Setter Property="VerticalAlignment" Value="Top"/> <Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="Width" Value="600"/> <Setter Property="Height" Value="400"/> </Trigger> </Style.Triggers> </Style> </Style.Resources> </Style> </ResourceDictionary>
加载XAML的运行时代码
string aspectRatio = File.ReadAllText("Data/Customization/AspectRatio/ExternalFile.xaml"); ResourceDictionary dictionaryAspectRatio = (ResourceDictionary)XamlReader.Parse(aspectRatio); Application.Current.Resources.MergedDictionaries.Add(dictionaryAspectRatio);
用户疑问
Xaml文件中的TargetType引用了自定义用户控件,因此我需要添加local:来访问命名空间。这会不会就是问题所在?有没有解决方法?
解决方法
1. 完善命名空间声明(最常见原因)
如果DemoElement所在程序集不是当前执行程序集,local命名空间需要补充程序集信息。修改XAML中的xmlns:local声明:
xmlns:local="clr-namespace:StyleDemo;assembly=StyleDemoAssemblyName"
将StyleDemoAssemblyName替换为DemoElement所在程序集的实际名称(无需加.dll后缀)。
2. 确保自定义类型符合要求
DemoElement必须是public修饰的类,XAML解析器无法访问非公共类型。- 类必须继承自
FrameworkElement或其子类(如UserControl、Control等),否则无法作为Style的TargetType。
3. 解析时指定ParserContext
如果命名空间映射仍有问题,可在代码中通过ParserContext显式指定命名空间,确保解析器能找到目标类型:
string aspectRatio = File.ReadAllText("Data/Customization/AspectRatio/ExternalFile.xaml"); ParserContext context = new ParserContext(); // 替换为实际的命名空间和程序集 context.XmlnsDictionary.Add("local", "clr-namespace:StyleDemo;assembly=StyleDemoAssemblyName"); ResourceDictionary dictionaryAspectRatio = (ResourceDictionary)XamlReader.Parse(aspectRatio, context); Application.Current.Resources.MergedDictionaries.Add(dictionaryAspectRatio);
4. 检查类型名称拼写
确认XAML中的local:DemoElement与实际类名完全一致,C#是大小写敏感语言,拼写错误会导致类型无法找到。
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

