类型列表的附加属性
我想创建一个可以与此语法一起使用的附加属性:
<Button>
<Image .../>
<ui:ToolbarItem.DisplayFilter>
<TabItem .../>
<TabItem .../>
<TabItem .../>
</ui:ToolbarItem.DisplayFilter>
</Button>
这是我这样做的尝试:
public class ToolbarItem
{
/// <summary>
/// Identifies the DisplayFilter attached property.
/// </summary>
public static readonly DependencyProperty DisplayFilterProperty =
DependencyProperty.RegisterAttached(
"DisplayFilter",
typeof( IList ),
typeof( ToolbarItem )
);
public static IList GetDisplayFilter( Control item ) {
return (IList)item.GetValue( DisplayFilterProperty );
}
public static void SetDisplayFilter( Control item, IList value ) {
item.SetValue( DisplayFilterProperty, value );
}
}
但是,这在解析时导致异常 - System.ArgumentException:TabItem 不是属性的有效值'显示过滤器'。那么如何配置我的附加属性以便我可以使用所需的 XAML 语法?
I want to create an attached property that can be used with this syntax:
<Button>
<Image .../>
<ui:ToolbarItem.DisplayFilter>
<TabItem .../>
<TabItem .../>
<TabItem .../>
</ui:ToolbarItem.DisplayFilter>
</Button>
This is my attempt at doing so:
public class ToolbarItem
{
/// <summary>
/// Identifies the DisplayFilter attached property.
/// </summary>
public static readonly DependencyProperty DisplayFilterProperty =
DependencyProperty.RegisterAttached(
"DisplayFilter",
typeof( IList ),
typeof( ToolbarItem )
);
public static IList GetDisplayFilter( Control item ) {
return (IList)item.GetValue( DisplayFilterProperty );
}
public static void SetDisplayFilter( Control item, IList value ) {
item.SetValue( DisplayFilterProperty, value );
}
}
This, however, is causing an exception at parse-time -- System.ArgumentException: TabItem is not a valid value for property 'DisplayFilter'. So how do I configure my attached property so that I can use the desired XAML syntax?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
请记住,XAML 基本上只是对象创建的简写形式。因此,要创建一个集合/列表作为附加的 DisplayFilter 属性的值,您必须将这些 TabItems 包含在另一个集合标记内。如果您不想这样做(这是可以理解的),则必须在第一次访问该属性时初始化该集合。
这样做只有一个问题:作为一种优化,XAML 读取器会跳过 getter 方法。您可以通过为
RegisterAttached
调用的 name 参数选择不同的名称来防止此行为:然后将调用属性 getter,您可以检查
null< /代码>。您可以在 此博文。
编辑:链接的博客文章似乎不太清楚。您仅更改传递给
RegisterAttached
的字符串名称,而不是静态get/set方法的名称:您必须在
GetDisplayFilter<中初始化集合/code> 方法:
看来您只将
TabItem
元素添加到该集合中。然后,您可以使集合类型安全,但使用IList
不起作用,因为 XAML 解析器无法调用泛型方法Add(T)
。Collection
和List
也实现非泛型IList
接口,并且可以在这种情况下使用。我建议创建一个新的集合类型,以防您将来想要对集合进行一些更改:如果您不关心像这样显式设置集合:
您可以删除
SetDisplayFilter
方法。总结:
Remember that XAML is basically just a shorthand form of object creation. So to create a collection/list as the value for the attached
DisplayFilter
property you would have to enclose thoseTabItems
inside another collection tag. If you don't want to do that, which is understandable, you have to initialize the collection the first time the property is accessed.There is just one problem with this: The getter method is skipped by the XAML reader as an optimization. You can prevent this behavior by choosing a different name for the name argument to the
RegisterAttached
call:Then the property getter will be called and you can check for
null
. You can read more about that in this blog post.Edit: Seems like the linked blog post isn't that clear. You change only the name of the string passed to
RegisterAttached
, not the name of the static get/set methods:You have to initialize the collection in the
GetDisplayFilter
method:It seems that you only add
TabItem
elements to that collection. Then you can make the collection type-safe, but usingIList<T>
does not work since the XAML parser cannot invoke the generic methodAdd(T)
.Collection<T>
andList<T>
also implement the non-genericIList
interface and can be used in this case. I would suggest to create a new collection type in case you want to do some changes to the collection in the future:If you don't care about setting the collection explicitly like this:
you can remove the
SetDisplayFilter
method.To summarize: