我使用一个定制的项目呈示,在一个组合框显示一种定制的绘图,而不是默认的案文的标签。

此作为拉的清单,但所显示的项目(当列表是封闭的)仍然是该文本表示我的对象。

有没有办法已经显示的项目呈现相同的方式作为一个在拉?

有帮助吗?

解决方案

默认情况下,您无法执行此操作。但是,如果扩展ComboBox,则可以轻松添加此功能。这是一个简单的例子,它是一个粗略的版本,可能需要测试/调整,但它显示了如何实现这一目标。

package
{
    import mx.controls.ComboBox;
    import mx.core.UIComponent;

    public class ComboBox2 extends ComboBox
    {
        public function ComboBox2()
        {
            super();
        }

        protected var textInputReplacement:UIComponent;

        override protected function createChildren():void {
            super.createChildren();

            if ( !textInputReplacement ) {
                if ( itemRenderer != null ) {
                    //remove the default textInput
                    removeChild(textInput);

                    //create a new itemRenderer to use in place of the text input
                    textInputReplacement = itemRenderer.newInstance();
                    addChild(textInputReplacement);
                }
            }
        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            super.updateDisplayList(unscaledWidth, unscaledHeight);

            if ( textInputReplacement ) {
                textInputReplacement.width = unscaledWidth;
                textInputReplacement.height = unscaledHeight;
            }
        }
    }
}

其他提示

我尝试了上述解决方案,但发现当组合框关闭时,selectedItem没有显示。需要额外的代码行才能将itemRenderer数据属性绑定到selectedItem:

            if ( !textInputReplacement ) {
                    if ( itemRenderer != null ) {
                            //remove the default textInput
                            removeChild(textInput);

                            //create a new itemRenderer to use in place of the text input
                            textInputReplacement = itemRenderer.newInstance();

                            // ADD THIS BINDING:
                            // Bind the data of the textInputReplacement to the selected item
                            BindingUtils.bindProperty(textInputReplacement, "data", this, "selectedItem", true);

                            addChild(textInputReplacement);
                    }
            }

我进一步扩展了Dane的代码。在某些情况下,点击没有打开我的渲染器的下拉框,我注意到正常的Flex ComboBox外观没有触发。因此,在 replaceTextInput()中,我添加了一些额外的事件侦听器,并保存对用于显示外观的ComboBox按钮的引用。现在它的行为就像普通的ComboBox一样。

以下是代码:

    package
    {
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;

    import mx.binding.utils.BindingUtils;
    import mx.controls.Button;
    import mx.controls.ComboBox;
    import mx.core.IFactory;
    import mx.core.UIComponent;
    import mx.events.DropdownEvent;

    /**
     * Extension of the standard ComboBox that will use the assigned 'itemRenderer'
     * for both the list items and the selected item.
     * 
     * Based on code from:
     * http://stackoverflow.com/questions/269773/flex-custom-item-renderer-for-the-displayed-item-in-the-combobox
     */
    public class ComboBoxFullRenderer extends ComboBox
    {
    protected var textInputReplacement:UIComponent;
    private var _increaseW:Number = 0;
    private var _increaseH:Number = 0;


    /**
     * Keeps track of the current open/close state of the drop down list. 
     */
    protected var _isOpen:Boolean = false;

    /**
     * Stores a reference to the 'Button' which overlays the ComboBox.  Allows
     * us to pass events to it so skins are properly triggered. 
     */
    protected var _buttonRef:Button = null;


    /**
     * Constructor. 
     */
    public function ComboBoxFullRenderer() {
        super();
    }


    /**
     * Sets a value to increase the width of our ComboBox to adjust sizing. 
     * 
     * @param val Number of pixels to increase the width of the ComboBox.
     */
    public function set increaseW(val:Number):void {
        _increaseW = val;
    }

    /**
     * Sets a value to increase the height of our ComboBox to adjust sizing. 
     * 
     * @param val Number of pixels to increase the height of the ComboBox.
     */
    public function set increaseH(val:Number):void {
        _increaseH = val;
    }


    /**
     * Override the 'itemRenderer' setter so we can also replace the selected
     * item renderer.
     *  
     * @param value The renderer to be used to display the drop down list items
     *   and the selected item.
     */
    override public function set itemRenderer(value:IFactory):void {
        super.itemRenderer = value;
        replaceTextInput();
    }


    /**
     * Override base 'createChildren()' routine to call our 'replaceTextInput()'
     * method to replace the standard selected item renderer.
     *  
     * @see #replaceTextInput();
     */
    override protected function createChildren():void {
        super.createChildren();
        replaceTextInput();
    }


    /**
     * Routine to replace the ComboBox 'textInput' child with our own child
     * that will render the selected data element.  Will create an instance of
     * the 'itemRenderer' set for this ComboBox. 
     */
    protected function replaceTextInput():void {
        if ( !textInputReplacement ) {
            if ( this.itemRenderer != null && textInput != null ) {
                //remove the default textInput
                removeChild(textInput);

                //create a new itemRenderer instance to use in place of the text input
                textInputReplacement = this.itemRenderer.newInstance();
                // Listen for clicks so we can open/close the drop down when
                // renderer components are clicked.  
                textInputReplacement.addEventListener(MouseEvent.CLICK, _onClick);
                // Listen to the mouse events on our renderer so we can feed them to
                // the ComboBox overlay button.  This will make sure the button skins
                // are activated.  See ComboBox::commitProperties() code.
                textInputReplacement.addEventListener(MouseEvent.MOUSE_DOWN, _onMouseEvent);
                textInputReplacement.addEventListener(MouseEvent.MOUSE_UP, _onMouseEvent);
                textInputReplacement.addEventListener(MouseEvent.ROLL_OVER, _onMouseEvent);
                textInputReplacement.addEventListener(MouseEvent.ROLL_OUT, _onMouseEvent);
                textInputReplacement.addEventListener(KeyboardEvent.KEY_DOWN, _onMouseEvent);

                // Bind the data of the textInputReplacement to the selected item
                BindingUtils.bindProperty(textInputReplacement, "data", this, "selectedItem", true);

                // Add our renderer as a child.
                addChild(textInputReplacement);

                // Listen for open close so we can maintain state.  The
                // 'isShowingDropdown' property is mx_internal so we don't
                // have access to it. 
                this.addEventListener(DropdownEvent.OPEN, _onOpen);
                this.addEventListener(DropdownEvent.CLOSE, _onClose);

                // Save a reference to the mx_internal button for the combo box.
                //  We will need this so we can call its dispatchEvent() method.
                for (var i:int = 0; i < this.numChildren; i++) {
                    var temp:Object = this.getChildAt(i);
                    if (temp is Button) {
                        _buttonRef = temp as Button;
                        break;
                    } 
                }
            }
        }
    }


    /**
     * Detect open events on the drop down list to keep track of the current
     * drop down state so we can react properly to a click on our selected
     * item renderer.
     *  
     * @param event The DropdownEvent.OPEN event for the combo box.
     */
    protected function _onOpen(event:DropdownEvent) : void {
        _isOpen = true;
    }


    /**
     * Detect close events on the drop down list to keep track of the current
     * drop down state so we can react properly to a click on our selected
     * item renderer.
     *  
     * @param event The DropdownEvent.CLOSE event for the combo box.
     */
    protected function _onClose(event:DropdownEvent) : void {
        _isOpen = false;
    }


    /**
     * When we detect a click on our renderer open or close the drop down list
     * based on whether the drop down is currently open/closed.
     *  
     * @param event The CLICK event from our selected item renderer.
     */
    protected function _onClick(event:MouseEvent) : void {
        if (_isOpen) {
            this.close(event);
        } else {
            this.open();
        }
    }


    /**
     * React to certain mouse/keyboard events on our selected item renderer and
     * pass the events to the ComboBox 'button' so that the skins are properly
     * applied.
     *  
     * @param event A mouse or keyboard event to send to the ComboBox button.
     * 
     */
    protected function _onMouseEvent(event:Event) : void {
        if (_buttonRef != null) {
            _buttonRef.dispatchEvent(event);
        }
    }
    } // end class
    } // end package

谢谢你maclema和Maurits de Boer.我加了几更多的事情要此类使它适合我需要:

  • 我推翻了集呈示器,以便这种会的工作,如果你设置通过作为呈示器而不是单.我移动的文字输入替代码,以其自身的功能,以避免工作重复。

  • 我加入者为'increaseW'和'increaseH'调整组合框如有必要,因为我渲染是太大的组合框在第一次。

  • 我减去25从textInputReplacement宽度,所以它不过重叠拉按钮...可以更好地使用更多的东西比例,以适应不同的皮肤,等等。

代码:

package
{
 import mx.binding.utils.BindingUtils;
 import mx.controls.ComboBox;
 import mx.core.IFactory;
 import mx.core.UIComponent;

    public class ComboBox2 extends ComboBox
    {
        public function ComboBox2()
        {
                super();
        }

        protected var textInputReplacement:UIComponent;
        private var _increaseW:Number = 0;
        private var _increaseH:Number = 0;

  public function set increaseW(val:Number):void
  {
   _increaseW = val;
  }

  public function set increaseH(val:Number):void
  {
   _increaseH = val;
  }

  override public function set itemRenderer(value:IFactory):void
  {
   super.itemRenderer = value;
   replaceTextInput();
  }

        override protected function createChildren():void 
        {
                super.createChildren();
    replaceTextInput();

        }

        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {

          unscaledWidth += _increaseW;
          unscaledHeight += _increaseH;

                super.updateDisplayList(unscaledWidth, unscaledHeight);

                if ( textInputReplacement ) {
                        textInputReplacement.width = unscaledWidth - 25;
                        textInputReplacement.height = unscaledHeight;
                }
        }

        protected function replaceTextInput():void
        {
         if ( !textInputReplacement ) {
                        if ( this.itemRenderer != null ) {
                                //remove the default textInput
                                removeChild(textInput);

                                //create a new itemRenderer to use in place of the text input
                                textInputReplacement = this.itemRenderer.newInstance();
                                addChild(textInputReplacement);

                                // ADD THIS BINDING:
                             // Bind the data of the textInputReplacement to the selected item
                             BindingUtils.bindProperty(textInputReplacement, "data", this, "selectedItem", true);

                             addChild(textInputReplacement);

                        }
                }
        }
    }
}

我一直在寻找使用Spark ComboBox的方法。

这个帖子对我来说非常有用,但到目前为止只有使用mx:ComboBox的答案。我认为我应该使用Spark ComboBox附加我的答案。

  1. 创建ComboBox的新外观
  2. 隐藏和禁用textInput
  3. 插入您自己的组件
  4. 这就是皮肤的样子:

    <s:SparkSkin>
    
        <... Lots of other stuff/>
    
        <s:BorderContainer height="25">
            <WHATEVER YOU NEED HERE!/>
        </s:BorderContainer>
    
        <!-- Disable the textInput and hide it -->
        <s:TextInput id="textInput"
            left="0" right="18" top="0" bottom="0" 
            skinClass="spark.skins.spark.ComboBoxTextInputSkin"
    
            visible="false" enabled="false"/> 
    
    
    </s:SparkSkin>
    

    使用Spark ComboBox,这个过程非常简单,不需要你扩展ComboBox。

我找到了一种更简单的方法来更改所选元素的渲染器。只有当您的元素继承自Flex 4.0或更高版本中的 TextInput 类时,此方法才有效。

在Flex v4.5中,在第1177行的 ComboBase.createChildren 中,您会发现可以使用样式键 textInput 可定义的类。 > textInputClass :

// Mechanism to use MXFTETextInput. 
var textInputClass:Class = getStyle("textInputClass");            
if (!textInputClass || FlexVersion.compatibilityVersion < FlexVersion.VERSION_4_0)
{
    textInput = new TextInput();
}
else
{
   textInput = new textInputClass();
}

只需在组合的构造函数中更改此键的值,现在您拥有自己的 selectedItem 的渲染器。

public function ComboAvailableProfessor()
{
    super();

    itemRenderer = new ClassFactory( ProfessorAvailableListItemRenderer );
    setStyle( 'textInputClass', ProfessorAvailableSelectedListItemRenderer );
}

最后,您必须将 data 属性绑定到组合中的 selectedItem 属性,以便显示数据。

override protected function createChildren():void
{
    super.createChildren();

    BindingUtils.bindProperty( textInput, 'data', this, 'selectedItem', true );
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top