我正在使用一個組合框自定義項目渲染顯示自定義繪製,而不是默認的文本標籤顯示的項目。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