2

我已经实现了一个自定义项目渲染器,我在我正在处理的 flex 项目中使用了一个组合框。它显示每个项目的图标和一些文本。唯一的问题是,当文本很长时,菜单的宽度没有被正确调整,并且在显示时文本被截断。我尝试调整所有明显的属性来缓解这个问题,但没有取得任何成功。有谁知道如何使组合框菜单宽度适当地缩放到它呈现的任何数据?

我的自定义项目渲染器实现是:

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml"
    styleName="plain" horizontalScrollPolicy="off"> 

    <mx:Image source="{data.icon}" />
    <mx:Label text="{data.label}" fontSize="11" fontWeight="bold" truncateToFit="false"/>

</mx:HBox>

我的组合框像这样使用它:

    <mx:ComboBox id="quicklinksMenu" change="quicklinkHandler(quicklinksMenu.selectedItem.data);" click="event.stopImmediatePropagation();" itemRenderer="renderers.QuickLinkItemRenderer" width="100%"/>

编辑:我应该澄清一下:我可以将组合框上的 dropdownWidth 属性设置为任意大的值 - 这将使一切都合适,但它会太宽。由于此组合框中显示的数据是通用的,因此我希望它自动将自身调整为 dataprovider 中最大的元素(flex 文档说它会这样做,但我觉得我的自定义项目渲染器以某种方式破坏了这种行为)

4

5 回答 5

1

只是一个随机的想法(不知道这是否会有所帮助):

尝试将父 HBox 和标签的宽度设置为 100%。这通常可以解决我遇到的任何类似问题。

于 2008-09-19T18:08:43.893 回答
0

您是否尝试过使用calculatePreferredSizeFromData()方法?

protected override function calculatePreferredSizeFromData(count:int):Object
于 2008-09-19T18:27:21.260 回答
0

这个答案可能为时已晚,但我对 DataGrid 的列宽有一个非常相似的问题。

经过多次思考,我决定在私有 TextField 中预渲染我的文本,从中获取渲染文本的宽度,并在所有适当的调整大小类型事件上显式设置列的宽度。有点hack-y,但如果你没有很多变化的数据,效果就足够了。

于 2008-09-30T21:37:18.190 回答
0

如果您查看 的measure方法mx.controls.ComboBase,您会看到组合框将其计算measuredMinWidth为文本宽度和组合框按钮宽度之和。

    // Text fields have 4 pixels of white space added to each side
    // by the player, so fudge this amount.
    // If we don't have any data, measure a single space char for defaults
    if (collection && collection.length > 0)
    {
        var prefSize:Object = calculatePreferredSizeFromData(collection.length);

        var bm:EdgeMetrics = borderMetrics;

        var textWidth:Number = prefSize.width + bm.left + bm.right + 8;
        var textHeight:Number = prefSize.height + bm.top + bm.bottom 
                    + UITextField.TEXT_HEIGHT_PADDING;

        measuredMinWidth = measuredWidth = textWidth + buttonWidth;
        measuredMinHeight = measuredHeight = Math.max(textHeight, buttonHeight);
    }

calculatePreferredSizeFromData@defmeta 提到的方法(在 中实现mx.controls.ComboBox)假设数据渲染器只是一个文本字段,并用于从对象flash.text.lineMetrics中的标签字段计算文本宽度data。如果您想向项目渲染器添加一个额外的视觉元素,并ComboBox在计算它自己的大小时考虑它的大小,您将必须扩展mx.controls.ComboBox类并重写该calculatePreferredSizeFromData方法,如下所示:

  override protected function calculatePreferredSizeFromData(count:int):Object
  {
      var prefSize:Object = super.calculatePrefferedSizeFromData(count);
      var maxW:Number = 0;
      var maxH:Number = 0;
      var bookmark:CursorBookmark = iterator ? iterator.bookmark : null;
      var more:Boolean = iterator != null;

      for ( var i:int = 0 ; i < count ; i++)
      {
          var data:Object;
          if (more) data = iterator ? iterator.current : null;
          else data = null;
          if(data)
          {
              var imgH:Number;
              var imgW:Number;

              //calculate the image height and width using the data object here

              maxH = Math.max(maxH, prefSize.height + imgH);
              maxW = Math.max(maxW, prefSize.width + imgW);
          }
          if(iterator) iterator.moveNext();
      }

      if(iterator) iterator.seek(bookmark, 0);
      return {width: maxW, height: maxH};
 }

如果可能,将图像尺寸存储在数据对象中并将这些值用作imgHimgW,这将使调整大小更加容易。

编辑:

maxH如果您要向渲染中添加除图像之外的元素(如标签),您还必须在遍历数据元素时计算它们的大小,并在计算和时考虑这些尺寸maxW

于 2009-11-06T16:14:36.680 回答
0

你需要做两件事:

  • 对于文本,使用mx.controls.Text(支持文本换行)而不是 mx.controls.Label
  • set comboBox's dropdownFactory.variableRowHeight=true-- 这个 dropdownFactory 通常是 List 的子类,您在 ComboBox 上设置的 itemRenderer 将用于渲染列表中的每个项目

并且,不要显式设置comboBox.dropdownWidth——让 h 的默认值comboBox.widt用作下拉菜单的宽度。

于 2009-09-16T10:02:55.233 回答