我正在使用一个组合框自定义项目渲染显示自定义绘制,而不是默认的文本标签显示的项目。Flex的自定义项目渲染在下拉列表
也能正常工作的下拉列表中,但所显示的项目(当列表关闭时)仍然是我的对象的文本表示。
有没有办法有显示的项目呈现方式的一个下拉一样吗?
我正在使用一个组合框自定义项目渲染显示自定义绘制,而不是默认的文本标签显示的项目。Flex的自定义项目渲染在下拉列表
也能正常工作的下拉列表中,但所显示的项目(当列表关闭时)仍然是我的对象的文本表示。
有没有办法有显示的项目呈现方式的一个下拉一样吗?
默认情况下,你不能做到这一点。但是,如果扩展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;
}
}
}
}
我试过上面的解决方案,但发现当combobox关闭时,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);
}
}
谢谢maclema和Maurits的德布尔。我加了一对夫妇更多的事情到这个类,使它适合我的需求:
我推翻设定的itemRenderer因此,如果您通过设定的itemRenderer AS而不是MXML这会奏效。我将文本输入替换代码移至其自己的函数以避免重复。
我为'increaseW'和'increaseH'添加了setter,以便在必要时调整组合框的大小,因为我的渲染器起初对于组合框来说太大了。
我从textInputReplacement宽度减去25,因此不会永远重复的下拉按钮...可以更好地使用更多的东西的比例,以适应不同的皮肤和这样。
代码:
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);
}
}
}
}
}
这可以更简单地实现,如果你只是在寻找某种与CSS属性自定义格式的文本。覆盖“get selectedLabel():String”函数以返回要在文本框中显示的任何字符串。如果您需要某种CSS,请在selectedLabel()方法中的textInput(this.textInput)上设置样式。
我一直在寻找一种方式来做到这一点使用Spark组合框。
此线程对我非常有用,但到目前为止,我国目前仅有如何使用MX做答案:组合框。我以为我应该附加我的答案,如何使用spark组合框来做到这一点。
这是皮肤会是什么样子:
<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。
我已经将Dane的代码进一步扩展了一点。在某些情况下,点击没有打开我的渲染器的下拉框,我注意到正常的Flex组合框皮肤没有触发。因此,在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
我发现改变渲染所选元素更简单的方法。只有当您的元素继承自Flex 4.0或更高版本中的TextInput
类时,此类才有效。
在Flex V4.5,在ComboBase.createChildren
在行1177,你会发现,该类可定义为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);
}
你能帮助我://删除默认为textInput \t \t \t \t \t removeChild之(为textInput); 对mx.core类型的值的隐式强制:ITextInput与不相关的类型flash.display:DisplayObject。 – 2016-08-25 06:52:43