我正在使用我想要自定义的树控件。树dataProvider
中的数据项具有应用于标记节点的属性name
,以及应用于选择若干嵌入图像之一的属性type
以用作一个图标。最简单的方法是使用labelField
和iconFunction
属性。
但是,我想开始使用项目渲染器并打开以后添加更复杂的自定义的大门,所以我尝试制作自己的项目渲染器。我扩展了TreeItemRenderer
类,如下所示,并在我的树控件中使用它:
class DirectoryItemRenderer extends TreeItemRenderer
{
[Embed("assets/directory/DefaultIcon.png")]
private static var _DEFAULT_ICON:Class;
// ... some more icons ...
override public function set data(value:Object):void
{
super.data = value; // let the base class take care of everything I didn't think of
if (value is Node) { // only handle the data if it's our own node class
switch ((value as Node).type) {
// ... some case clauses ...
default:
this._vSetIcon(_DEFAULT_ICON);
}
this.label.text = (value as Node).name;
}
}
private function _vSetIcon(icon:Class):void
{
if (null != this.icon && this.contains(this.icon)) {
this.removeChild(this.icon);
}
this.icon = new icon();
this.addChild(this.icon);
this.invalidateDisplayList();
}
}
此代码无效,树控件中的图标和标签保持默认值。使用trace()
,我验证了我的代码实际执行完毕。我做错了什么?
答案 0 :(得分:0)
我可能会尝试一些简单的事情,例如Adobe Cookbooks中的this example。我注意到它们会覆盖updateDisplayList
,这可能与您的问题有关。
有another example(适用于Flex 2,但看起来适用于Flex 3),它显示了如何管理默认图标。看起来你想要自己管理图标,将默认图标样式设置为null,而不是试图操纵超类的图标属性。
更新 - 查看TreeItemRenderer的来源,commitProperties
在检查数据并设置图标和标签之前有以下内容:
if (icon)
{
removeChild(DisplayObject(icon));
icon = null;
}
此外,它似乎是data
调用invalidateProperties
的设置器。因此,当框架调用commitProperties
时,您的图标就会被清除。
答案 1 :(得分:0)
查看基础mx.controls.treeClasses.TreeItemRenderer
类,我看到updateDisplayList
函数中的渲染器从icon
获取了disclosureIcon
和_listData:TeeListData
类。不要覆盖updateDisplayList
函数,而是尝试使用公共访问器修改icon
方法中渲染器的私有disclosureIcon
实例的_listData
和_vSetIcon
类,例如这样:
private function _vSetIcon(icon:Class, disclosureIcon:Class = null):void
{
var tmpListData:TreeListData;
if (disclosureIcon == null) disclosureIcon = icon;
tmpListData = this.listData;
tmpListData.icon = icon;
tmpListData.disclosureIcon = disclosureIcon;
this.listData = tmpListData;
}
编辑
以下是对data
和listData
之间区别的一些说明。你不得不原谅我对包裹名称的遗漏,但是我正在用我的手机进行编辑,因此很难查找它们,而且我不知道包装名称是否在我的头顶。 data
是在TreeItemRenderer
界面中IDataRenderer
的上下文中定义的。您可以通过实现此接口并定义公共属性data
来创建数据渲染器,在这种情况下,公共属性由父控件设置,并包含来自dataProvider
的一些数据和元数据。数据渲染器类。
listData
在IDropInListItemRenderer
接口中定义为BaseListData
类型的属性,并在TreeItemRenderer
类中实现为属性TreeListData
。它与data
属性的不同之处在于它包含描述TreeListRenderer
本身(图标,缩进,打开)的元数据以及(我相信,稍后我将不得不仔细检查)对正在呈现的数据项的引用。我收集它TreeItemRenderer
使用它,我会想象父列表控件用于显示更新和大小调整的目的。有人可以自由纠正或添加,如果我不正确或遗漏了某些东西,我会按照我记得的代码进行修改。
在这种情况下,您希望使用来自数据提供程序的数据集中的元数据来修改确定渲染器显示的数据,因此您需要同时修改它们。
我认为真正的困惑来自于你扩展了TreeItemRenderer
类,然后尝试以原始开发人员不打算让某人做的方式覆盖组件上的功能,因此出乎意料结果。如果你的目标是教育而不是易于实现,那么扩展UIComponent
类并使用TreeItemRenderer
代码作为参考来创建实现相同接口的类可能会更好。这将是对自定义组件开发池的真正潜入。