UIElementCollection
2015-08-20 09:57
399 查看
逻辑树:
逻辑树描述的是用户界面元素之间的关系,它主要负责:
传承依赖属性的值
设定动态资源的引用
为绑定查询元素的名称
传递路由事件
视图树:
视图树包括每一个逻辑元素的模板中的所有视图元素。它的责任是:
显示视图元素
设定元素的透明度
设定元素的布局和渲染变化
设定元素的可用(IsEnable)属性
做命中测试
关联资源(寻根)
Panel类的Childrend属性的类型是UIElementCollection
Panel类暴露了一个类型为UIElement的公有属性“Children”。Panel类重写了VisualChildrenCount属性和GetVisualChild()方法,将Children集合中的成员作为它的可视子元素返回。Panel也使用重写的GetVisualChild()方法为Children集合中的成员提供z-ordering。
UIElementCollection提供一种非常便捷的方式提供任何元素(可视元素或逻辑元素),不仅仅是面板。
一个元素可以简单地创建一个UIElementCollection的实例并将该元素自己作为集合的可视父元素。然后,任何被添加到集合的UIElement实例都将自动地被视为可视子元素添加到这个元素中。如果在创建集合的时候指定了一个逻辑元素,UIElement实例也会被视为逻辑子元素添加到这个元素中。
UIElementCollection的构造方法如下:
Panel类创建UIElementCollection的方法如下:
从CreateUIElementCollection的实现可以看到,Panel将自身作为集合的可视父元素。因此在将UIElement添加到UIElementCollection中时,UIElementCollection内部会自动将该UIElement元素添加到以Panel作为可视父元素的可视树中,这样子元素就呈现出来了。
可以看出如果Panel的IsItemsHost属性为true的话,UIElementCollection的logicalParent将为null。之所以设置为null是因为此时的LogicalParent应该是ItemsControl类或者它的子类型。如果按常规的方式使用Panel,则LogicalParent就是Panel自身,此时LogicalParent和VisualParent相同。
如果Panel的IsItemHost属性为true的话,UIElementCollection会阻止对内部集合的直接修改,只能通过ItemsControl间接地修改。不过UIElementCollection有一个后门允许在IsItemsHost为true的情况下修改内部的集合。这个方法就是通过与ItemsControl关联的ItemContainerGenerator来访问内部集合。
UIElementCollection将成员存储在内部的VisualCollection集合中。
UIElementCollection被创建时会在内部实例化一个VisualCollection类型的集合,这个集合才是真正设置可视父元素和存储Child的地方,同时这个集合还维护者可视父元素与Child之间的关系。UIElementCollection扩展了VisualCollection的功能,增加了维护逻辑父元素和Child之间关系的部分。
UIElementCollection在添加子元素时,如果LogicalParent不为null,会将子元素也添加到逻辑树中
UIElementCollection看上去是可以扩展的,因为它暴露了很多虚方法。此外Panel类也暴露了一个虚方法CreateUIElementCollection,我们可以重写这个方法来创建一个自定义的集合,这个集合必须继承自UIElementCollection。这个自定义集合还必须监听集合的改变,这可以通过重写一些方法:Add,Clear,Insert,Remove,RemoveAt等等。
逻辑树描述的是用户界面元素之间的关系,它主要负责:
传承依赖属性的值
设定动态资源的引用
为绑定查询元素的名称
传递路由事件
视图树:
视图树包括每一个逻辑元素的模板中的所有视图元素。它的责任是:
显示视图元素
设定元素的透明度
设定元素的布局和渲染变化
设定元素的可用(IsEnable)属性
做命中测试
关联资源(寻根)
Panel类的Childrend属性的类型是UIElementCollection
Panel类暴露了一个类型为UIElement的公有属性“Children”。Panel类重写了VisualChildrenCount属性和GetVisualChild()方法,将Children集合中的成员作为它的可视子元素返回。Panel也使用重写的GetVisualChild()方法为Children集合中的成员提供z-ordering。
public abstract class Panel : FrameworkElement, IAddChild { ...... private UIElementCollection _uiElementCollection; ...... protected internal UIElementCollection InternalChildren { get { this.VerifyBoundState(); if (this.IsItemsHost) { this.EnsureGenerator(); } else if (this._uiElementCollection == null) { this.EnsureEmptyChildren(this); } return this._uiElementCollection; } } ...... protected override int VisualChildrenCount { get { if (this._uiElementCollection == null) { return 0; } return this._uiElementCollection.Count; } } protected override Visual GetVisualChild(int index) { if (this._uiElementCollection == null) { throw new ArgumentOutOfRangeException("index", index, SR.Get("Visual_ArgumentOutOfRange")); } if (this.IsZStateDirty) { this.RecomputeZState(); } int index2 = (this._zLut != null) ? this._zLut[index] : index; return this._uiElementCollection[index2]; } protected virtual UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent) { return new UIElementCollection(this, logicalParent); } }
UIElementCollection提供一种非常便捷的方式提供任何元素(可视元素或逻辑元素),不仅仅是面板。
一个元素可以简单地创建一个UIElementCollection的实例并将该元素自己作为集合的可视父元素。然后,任何被添加到集合的UIElement实例都将自动地被视为可视子元素添加到这个元素中。如果在创建集合的时候指定了一个逻辑元素,UIElement实例也会被视为逻辑子元素添加到这个元素中。
UIElementCollection的构造方法如下:
public UIElementCollection(UIElement visualParent, FrameworkElement logicalParent)
Panel类创建UIElementCollection的方法如下:
protected virtual UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent) { return new UIElementCollection(this, logicalParent); }
从CreateUIElementCollection的实现可以看到,Panel将自身作为集合的可视父元素。因此在将UIElement添加到UIElementCollection中时,UIElementCollection内部会自动将该UIElement元素添加到以Panel作为可视父元素的可视树中,这样子元素就呈现出来了。
protected internal UIElementCollection InternalChildren { get { this.VerifyBoundState(); if (this.IsItemsHost) { this.EnsureGenerator(); } else if (this._uiElementCollection == null) { this.EnsureEmptyChildren(this); } return this._uiElementCollection; } }
<span style="color: #0000ff; "><strong>internal</strong></span> <span style="color: #ff0000; ">void</span> <span style="color: #191970; "><strong>EnsureGenerator</strong></span>() { <span style="color: #0000ff; "><strong>if</strong></span> (<span style="font-weight: bold; ">this</span>._itemContainerGenerator == <span style="font-weight: bold; ">null</span>) { <span style="font-weight: bold; ">this</span>.<span style="color: #191970; "><strong>ConnectToGenerator</strong></span>(); <span style="font-weight: bold; ">this</span>.<span style="color: #191970; "><strong>EnsureEmptyChildren</strong></span>(<span style="font-weight: bold; ">null</span>); <span style="font-weight: bold; ">this</span>.<span style="color: #191970; "><strong>GenerateChildren</strong></span>(); } }
可以看出如果Panel的IsItemsHost属性为true的话,UIElementCollection的logicalParent将为null。之所以设置为null是因为此时的LogicalParent应该是ItemsControl类或者它的子类型。如果按常规的方式使用Panel,则LogicalParent就是Panel自身,此时LogicalParent和VisualParent相同。
如果Panel的IsItemHost属性为true的话,UIElementCollection会阻止对内部集合的直接修改,只能通过ItemsControl间接地修改。不过UIElementCollection有一个后门允许在IsItemsHost为true的情况下修改内部的集合。这个方法就是通过与ItemsControl关联的ItemContainerGenerator来访问内部集合。
UIElementCollection将成员存储在内部的VisualCollection集合中。
UIElementCollection被创建时会在内部实例化一个VisualCollection类型的集合,这个集合才是真正设置可视父元素和存储Child的地方,同时这个集合还维护者可视父元素与Child之间的关系。UIElementCollection扩展了VisualCollection的功能,增加了维护逻辑父元素和Child之间关系的部分。
UIElementCollection在添加子元素时,如果LogicalParent不为null,会将子元素也添加到逻辑树中
public virtual UIElement this[int index] { get { return this._visualChildren[index] as UIElement; } set { this.VerifyWriteAccess(); this.ValidateElement(value); VisualCollection visualChildren = this._visualChildren; if (visualChildren[index] != value) { UIElement uIElement = visualChildren[index] as UIElement; if (uIElement != null) { this.ClearLogicalParent(uIElement); } visualChildren[index] = value; this.SetLogicalParent(value); this._visualParent.InvalidateMeasure(); } } }
<span style="color: #0000ff; "><strong>protected</strong></span> <span style="color: #ff0000; ">void</span> <span style="color: #191970; "><strong>SetLogicalParent</strong></span>(UIElement element) { <span style="color: #0000ff; "><strong>if</strong></span> (<span style="font-weight: bold; ">this</span>._logicalParent != <span style="font-weight: bold; ">null</span>) { <span style="font-weight: bold; ">this</span>._logicalParent.<span style="color: #191970; "><strong>AddLogicalChild</strong></span>(element); } }
UIElementCollection看上去是可以扩展的,因为它暴露了很多虚方法。此外Panel类也暴露了一个虚方法CreateUIElementCollection,我们可以重写这个方法来创建一个自定义的集合,这个集合必须继承自UIElementCollection。这个自定义集合还必须监听集合的改变,这可以通过重写一些方法:Add,Clear,Insert,Remove,RemoveAt等等。
相关文章推荐
- dpkg: error processing package bluez (--configure) 解决方法
- 【转载】使用SoapUI 测试Web Service
- 后台UI模板开发规范
- NGUI sprite 裁剪到其他图片sprite
- UITableView总结
- Algorithms—128.Longest Consecutive Sequence
- Handler详解(二)---关联到非UI线程
- 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别
- UITextView 监听点击了returnKey 的方法
- Qt:将quick的控件图像保存为QImage
- iOS UI16_数据持久化
- Xcode环境变量 build Settings 设置
- iOS 9学习系列:UIStackView如何让你的开发更简单
- PHP中 include, include_once, require, require_once的区别
- Havok_2014-1-0_Pc_Xs_User_Guide(2.2.1-创建一个Physics2012对象)
- IOS开发UI阶段 第六周
- iOS开发笔记--iphone练习之手势识别(双击、捏、旋转、拖动、划动、长按)UITapGestureRecognize
- poj 1679 The Unique MST 【次小生成树+100的小数据量】
- iOS多线程-03-NSOperation与NSOperationQueue
- 发现UITableView留白问题解决办法