简体   繁体   English

Flex:组合框的自定义项目渲染器控件将截断文本

[英]Flex: Custom Item Renderer For Combobox controls truncates text

I've implemented a custom item renderer that I'm using with a combobox on a flex project I'm working on. 我已经实现了一个自定义项目渲染器,该项目渲染器正在与我正在处理的Flex项目上的组合框一起使用。 It displays and icon and some text for each item. 它显示每个项目的图标和一些文本。 The only problem is that when the text is long the width of the menu is not being adjusted properly and the text is being truncated when displayed. 唯一的问题是,当文本较长时,菜单的宽度不能正确调整,显示时文本将被截断。 I've tried tweaking all of the obvious properties to alleviate this problem but have not had any success. 我曾尝试调整所有明显的属性来缓解此问题,但均未成功。 Does anyone know how to make the combobox menu width scale appropriately to whatever data it's rendering? 有谁知道如何使组合框菜单的宽度适当地缩放以使其呈现任何数据?

My custom item renderer implementation is: 我的自定义项目渲染器实现是:

<?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>

And my combobox uses it like so: 我的组合框像这样使用它:

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

EDIT: I should clarify on thing: I can set the dropdownWidth property on the combobox to some arbitrarily large value - this will make everything fit, but it will be too wide. 编辑:我应该澄清的事情:我可以将组合框上的dropdownWidth属性设置为任意大的值-这将使所有内容都适合,但它会太宽。 Since the data being displayed in this combobox is generic, I want it to automatically size itself to the largest element in the dataprovider (the flex documentation says it will do this, but I have the feeling my custom item renderer is somehow breaking that behavior) 由于此组合框中显示的数据是通用的,因此我希望它自动将其自身大小调整为数据提供程序中的最大元素(flex文档说它将做到这一点,但是我感到我的自定义项目渲染器某种程度上破坏了该行为)

Just a random thought (no clue if this will help): 只是一个随机的想法(不知道是否有帮助):

Try setting the parent HBox and the Label's widths to 100%. 尝试将父级HBox和Label的宽度设置为100%。 That's generally fixed any problems I've run into that were similar. 这通常可以解决我遇到的任何类似问题。

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

protected override function calculatePreferredSizeFromData(count:int):Object

You would need to do two things: 您将需要做两件事:

  • for the text, use mx.controls.Text (that supports text wrapping) instead of mx.controls.Label 对于文本,请使用mx.controls.Text (支持文本换行)而不是mx.controls.Label
  • set comboBox's dropdownFactory.variableRowHeight=true -- this dropdownFactory is normally a subclass of List, and the itemRenderer you are setting on ComboBox is what will be used to render each item in the list 设置comboBox的dropdownFactory.variableRowHeight=true true-此dropdownFactory通常是List的子类,您在ComboBox上设置的itemRenderer将用于呈现列表中的每个项目

And, do not explicitly set comboBox.dropdownWidth -- let the default value of comboBox.widt h be used as dropdown width. 而且,这样做没有明确设置comboBox.dropdownWidth -让我们的默认值comboBox.widt ^ h作为下拉列表的宽度。

This answer is probably too late, but I had a very similar problem with the DataGrid's column widths. 这个答案可能为时已晚,但是我对DataGrid的列宽有一个非常相似的问题。

After much noodling, I decided to pre-render my text in a private TextField, get the width of the rendered text from that, and explicitly set the width of the column on all of the appropriate resize type events. 经过大量的整理之后,我决定在私有TextField中预渲染文本,从中获取渲染文本的宽度,并在所有适当的调整大小类型事件上显式设置列的宽度。 A little hack-y but works well enough if you haven't got a lot of changing data. 有点骇人听闻,但如果您没有太多更改数据,则效果很好。

If you look at the measure method of mx.controls.ComboBase , you'll see that the the comboBox calculates it's measuredMinWidth as a sum of the width of the text and the width of the comboBox button. 如果您看一下mx.controls.ComboBasemeasure方法,您会看到comboBox计算它的measuredMinWidth是文本宽度和comboBox按钮的宽度之和。

    // 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);
    }

The calculatePreferredSizeFromData method mentioned by @defmeta (implemented in mx.controls.ComboBox ) assumes that the data renderer is just a text field, and uses flash.text.lineMetrics to calculate the text width from label field in the data object. @defmeta(在mx.controls.ComboBox实现)提到的calculatePreferredSizeFromData方法假定数据渲染器只是一个文本字段,并使用flash.text.lineMetricsdata对象中的标签字段计算文本宽度。 If you want to add an additional visual element to the item renderer and have the ComboBox take it's size into account when calculating it's own size, you will have to extend the mx.controls.ComboBox class and override the calculatePreferredSizeFromData method like so: 如果你想一个额外的视觉元素添加到项目渲染器,并具有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};
 }

If possible store the image dimensions in the data object and use those values as imgH and imgW , that will make sizing much easier. 如果可能的话,将图像尺寸存储在数据对象中,并将这些值用作imgHimgW ,这将使尺寸调整变得更加容易。

EDIT: 编辑:

If you are adding elements to the render besides an image, like a label, you will also have to calculate their size as well when you iterate through the data elements and take those dimensions into account when calculating maxH and maxW . 如果要在图像之外向渲染器添加元素(如标签),则在遍历数据元素时还必须计算其大小,并在计算maxHmaxW时将这些尺寸考虑maxW

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM