看项目代码的时候遇到的一种界面设计,关于自定义容器控件和附加属性的,之前没遇到过。
看下面这段Xaml代码:

每一个ListBox里面有一个附加属性:

其中ui:Form是我的自定义容器控件:
cs
public class Form : ItemsControl
{
static Form()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Form), new FrameworkPropertyMetadata(typeof(Form)));
IsTabStopProperty.OverrideMetadata(typeof(Form), new FrameworkPropertyMetadata(false));
}
//确定Item是否是(或者是否可以作为)其自己的Container
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is FormItem || item is FormHeader || item is Form;
}
//用于返回Item的Container
//即如果Item的类型不是FormItem,就将它作使用FormItem包装起来
protected override DependencyObject GetContainerForItemOverride()
{
return new FormItem();
}
}
界面效果是下面这样:

红色框起来的是LIstBox,黄色框的是Label。
我很疑惑这些Label控件是怎么来的。
经过我的寻找:

我发现这种样式是针对FormItem的,FormItem也是自定义的控件,并且在自定义容器控件Form中有涉及到:
cs
protected override DependencyObject GetContainerForItemOverride()
{
return new FormItem();
}
查阅了相关资料,明白了其中缘由:
如果ItemsControl的Items内容不是对应的子元素控件,ItemsControl会创建对应的子元素控件作为容器再把Item放进去
上面GetContainerForItemOverride的作用就是在ListBox和TextBox外包裹一个FormItem控件;
也可以理解为虽然在Xaml中代码没有写上FormItem控件,但是在容器控件CS代码中有写;
在界面的视觉树中可以体现:


结构与FormItem定义的样式相同。