动态生成模板中使用附加属性引发XamlParseException问题求助
问题
我在动态模板中使用附加属性时遇到了问题。
我正在编写一个自定义控件,用于显示集合中的项,希望允许控件使用者提供DisplayMemberPath,通过XamlReader生成ItemTemplate实现,代码如下:
private DataTemplate CreateItemTemplate() { StringReader stringReader = new StringReader( $@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:local=""clr-namespace:MyControl""> <TextBlock Text=""{{Binding {DisplayMemberPath}}}"" /> </DataTemplate>"); XmlReader xmlReader = XmlReader.Create(stringReader); return XamlReader.Load(xmlReader) as DataTemplate; }
现在想添加附加属性来为模板增加额外行为,比如这个简单的字符串附加属性:
internal class Foobar { public static readonly DependencyProperty BazProperty = DependencyProperty.RegisterAttached( "Baz", typeof(string), typeof(Foobar), new FrameworkPropertyMetadata(string.Empty, OnTextChanged)); public static string GetBaz(FrameworkElement frameworkElement) => (string)frameworkElement.GetValue(BazProperty); public static void SetBaz(FrameworkElement frameworkElement, string value) => frameworkElement.SetValue(BazProperty, value); private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { } }
我可以在视图XAML中直接使用这个附加属性,没有问题。但如果尝试在模板中使用该属性,运行时会触发XamlParseException,提示“Cannot set unknown member "{clr-namespace:MyControl}Foobar.Baz"”,修改后的代码如下:
private DataTemplate CreateItemTemplate() { StringReader stringReader = new StringReader( $@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:local=""clr-namespace:MyControl""> <TextBlock Text=""{{Binding {DisplayMemberPath}}}"" local:Foobar.Baz=""Baz"" /> </DataTemplate>"); XmlReader xmlReader = XmlReader.Create(stringReader); return XamlReader.Load(xmlReader) as DataTemplate; }
我遗漏了什么?
编辑:除了Sinus32的解答外,我还必须将定义附加属性的类的访问修饰符从
internal改为public。
解决方法
- 调整附加属性类的访问权限:将定义附加属性的
Foobar类的访问修饰符从internal改为public。XamlReader加载动态XAML时,需要能够访问到附加属性的定义类,内部类无法被XAML解析器识别,这是触发异常的核心原因之一。 - 验证XAML命名空间声明:确认XAML中的
local命名空间指向正确。如果Foobar类所在的程序集与当前控件程序集不同,需要在命名空间声明中补充程序集名称,格式为xmlns:local="clr-namespace:MyControl;assembly=MyControlAssemblyName"。 - 检查附加属性注册逻辑:确保
RegisterAttached方法的参数完全正确,尤其是所有者类型(typeof(Foobar))和属性名称("Baz")要与XAML中使用的名称完全匹配,避免拼写错误。
内容的提问来源于stack exchange,提问作者Flowly
相关产品推荐
相关产品推荐

