代码之家  ›  专栏  ›  技术社区  ›  James McMahon

如何使用扩展的treeitemrenderer在flex中更改树控件中节点的外观?

  •  1
  • James McMahon  · 技术社区  · 15 年前

    我正在使用我要自定义的树控件。树中的数据项 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() ,我验证了我的代码实际上是被执行的。我做错了什么?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Ryan Lynch    15 年前

    看着基地 mx.controls.treeClasses.TreeItemRenderer 班上,我在 updateDisplayList 函数渲染器获取 icon disclosureIcon 类来自 _listData:TeeListData . 而不是覆盖 更新显示列表 函数,尝试修改 偶像 披露图标 渲染器的私有类 _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 .你得原谅我漏掉了包裹名,但我在手机上编辑,所以很难查到它们,而且我也不知道包裹名。 数据 是在 TreeItemRenderer IDataRenderer 接口。通过实现此接口并定义公共属性,可以创建数据呈现器 数据 ,在本例中,它由父控件设置,并包含来自 dataProvider 将由数据呈现器类呈现。

    列表数据 在中定义 IDropInListItemRenderer 接口作为类型的属性 BaseListData 实现于 树项渲染器 类作为属性 TreeListData . 它不同于 数据 属性,其中包含描述 TreeListRenderer 它本身(icon、indent、open)以及(我相信,稍后必须再次检查)对正在呈现的数据项的引用。我猜它被 树项渲染器 我可以想象父列表控件用于显示更新和调整大小。有人可以随意更正或补充,如果我不正确或遗漏了一些东西,我会去做我记忆中的代码。

    在这种情况下,您希望使用来自数据提供程序的数据集的元数据来修改决定渲染器显示的数据,因此您需要同时修改这两个数据集。

    但我认为真正的困惑来自于你把 树项渲染器 然后,类尝试以原始开发人员不希望有人这样做的方式重写组件上的功能,从而产生意外的结果。如果您的目标是教育而不是易于实施,那么扩展 UIComponent 类和使用 树项渲染器 代码作为引用来创建实现相同接口的类。这将是对定制组件开发池的真正深入研究。

        2
  •  0
  •   Sam Martin    15 年前

    我可能会尝试一些简单的方法,比如 this example 来自Adobe食谱。我注意到它们覆盖了 updateDisplayList 这可能与你的问题有关。

    another example (对于flex 2,但似乎适用于flex 3),显示如何管理默认图标。看起来您需要自己管理图标,将默认图标样式设置为空,而不是尝试操作超类的图标属性。

    更新 --查看treeitemrenderer的源, commitProperties 在检查数据和设置图标和标签之前具有以下内容:

    if (icon)
    {
        removeChild(DisplayObject(icon));
        icon = null;
    }
    

    而且,它看起来像 data 电话 invalidateProperties . 因此,当框架开始调用 佣金属性 .

    推荐文章