我有一个继承自ComboBox的类。我想实现一个函数来控制游标的位置。任何内置函数? 提前谢谢
////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved. The following is Source Code and is subject to all
// restrictions on such code as contained in the End User License Agreement
// accompanying this product.
//
////////////////////////////////////////////////////////////////////////////////
package ac
{
import flash.events.KeyboardEvent;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.net.SharedObject;
import flash.ui.Keyboard;
import mx.core.UIComponent;
import mx.controls.ComboBox;
import mx.collections.ArrayCollection;
import mx.collections.ListCollectionView;
//--------------------------------------
// Events
//--------------------------------------
/**
* Dispatched when the <code>filterFunction</code> property changes.
*
* You can listen for this event and update the component
* when the <code>filterFunction</code> property changes.</p>
*
* @eventType flash.events.Event
*/
[Event(name="filterFunctionChange", type="flash.events.Event")]
/**
* Dispatched when the <code>typedText</code> property changes.
*
* You can listen for this event and update the component
* when the <code>typedText</code> property changes.</p>
*
* @eventType flash.events.Event
*/
[Event(name="typedTextChange", type="flash.events.Event")]
//--------------------------------------
// Excluded APIs
//--------------------------------------
[Exclude(name="editable", kind="property")]
/**
* The AutoComplete control is an enhanced
* TextInput control which pops up a list of suggestions
* based on characters entered by the user. These suggestions
* are to be provided by setting the <code>dataProvider
* </code> property of the control.
* @mxml
*
* <p>The <code><fc:AutoComplete></code> tag inherits all the tag attributes
* of its superclass, and adds the following tag attributes:</p>
*
* <pre>
* <fc:AutoComplete
* <b>Properties</b>
* keepLocalHistory="false"
* lookAhead="false"
* typedText=""
* filterFunction="<i>Internal filter function</i>"
*
* <b>Events</b>
* filterFunctionChange="<i>No default</i>"
* typedTextChange="<i>No default</i>"
* />
* </pre>
*
* @includeExample ../../../../../../docs/com/adobe/flex/extras/controls/example/AutoCompleteCountriesData/AutoCompleteCountriesData.mxml
*
* @see mx.controls.ComboBox
*
*/
public class AutoComplete extends ComboBox
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*/
public function AutoComplete()
{
super();
//Make ComboBox look like a normal text field
editable = true;
if(keepLocalHistory)
addEventListener("focusOut",focusOutHandler);
setStyle("arrowButtonWidth",0);
setStyle("fontWeight","normal");
setStyle("cornerRadius",0);
setStyle("paddingLeft",0);
setStyle("paddingRight",0);
rowCount = 7;
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var cursorPosition:Number=0;
/**
* @private
*/
private var prevIndex:Number = -1;
/**
* @private
*/
private var removeHighlight:Boolean = false;
/**
* @private
*/
private var showDropdown:Boolean=false;
/**
* @private
*/
private var showingDropdown:Boolean=false;
/**
* @private
*/
private var tempCollection:Object;
/**
* @private
*/
private var usingLocalHistory:Boolean=false;
/**
* @private
*/
private var dropdownClosed:Boolean=true;
//--------------------------------------------------------------------------
//
// Overridden Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// editable
//----------------------------------
/**
* @private
*/
override public function set editable(value:Boolean):void
{
//This is done to prevent user from resetting the value to false
super.editable = true;
}
/**
* @private
*/
override public function set dataProvider(value:Object):void
{
super.dataProvider = value;
if(!usingLocalHistory)
tempCollection = value;
}
//----------------------------------
// labelField
//----------------------------------
/**
* @private
*/
override public function set labelField(value:String):void
{
super.labelField = value;
invalidateProperties();
invalidateDisplayList();
}
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// filterFunction
//----------------------------------
/**
* @private
* Storage for the filterFunction property.
*/
private var _filterFunction:Function = defaultFilterFunction;
/**
* @private
*/
private var filterFunctionChanged:Boolean = true;
[Bindable("filterFunctionChange")]
[Inspectable(category="General")]
/**
* A function that is used to select items that match the
* function's criteria.
* A filterFunction is expected to have the following signature:
*
* <pre>f(item:~~, text:String):Boolean</pre>
*
* where the return value is <code>true</code> if the specified item
* should displayed as a suggestion.
* Whenever there is a change in text in the AutoComplete control, this
* filterFunction is run on each item in the <code>dataProvider</code>.
*
* <p>The default implementation for filterFunction works as follows:<br>
* If "AB" has been typed, it will display all the items matching
* "AB~~" (ABaa, ABcc, abAc etc.).</p>
*
* <p>An example usage of a customized filterFunction is when text typed
* is a regular expression and we want to display all the
* items which come in the set.</p>
*
* @example
* <pre>
* public function myFilterFunction(item:~~, text:String):Boolean
* {
* public var regExp:RegExp = new RegExp(text,"");
* return regExp.test(item);
* }
* </pre>
*
*/
public function get filterFunction():Function
{
return _filterFunction;
}
/**
* @private
*/
public function set filterFunction(value:Function):void
{
//An empty filterFunction is allowed but not a null filterFunction
if(value!=null)
{
_filterFunction = value;
filterFunctionChanged = true;
invalidateProperties();
invalidateDisplayList();
dispatchEvent(new Event("filterFunctionChange"));
}
else
_filterFunction = defaultFilterFunction;
}
//----------------------------------
// filterFunction
//----------------------------------
/**
* @private
* Storage for the keepLocalHistory property.
*/
private var _keepLocalHistory:Boolean = false;
/**
* @private
*/
private var keepLocalHistoryChanged:Boolean = true;
[Bindable("keepLocalHistoryChange")]
[Inspectable(category="General")]
/**
* When true, this causes the control to keep track of the
* entries that are typed into the control, and saves the
* history as a local shared object. When true, the
* completionFunction and dataProvider are ignored.
*
* @default "false"
*/
public function get keepLocalHistory():Boolean
{
return _keepLocalHistory;
}
/**
* @private
*/
public function set keepLocalHistory(value:Boolean):void
{
_keepLocalHistory = value;
}
//----------------------------------
// lookAhead
//----------------------------------
/**
* @private
* Storage for the lookAhead property.
*/
private var _lookAhead:Boolean=false;
/**
* @private
*/
private var lookAheadChanged:Boolean;
[Bindable("lookAheadChange")]
[Inspectable(category="Data")]
/**
* lookAhead decides whether to auto complete the text in the text field
* with the first item in the drop down list or not.
*
* @default "false"
*/
public function get lookAhead():Boolean
{
return _lookAhead;
}
/**
* @private
*/
public function set lookAhead(value:Boolean):void
{
_lookAhead = value;
lookAheadChanged = true;
}
//----------------------------------
// typedText
//----------------------------------
/**
* @private
* Storage for the typedText property.
*/
private var _typedText:String="";
/**
* @private
*/
private var typedTextChanged:Boolean;
[Bindable("typedTextChange")]
[Inspectable(category="Data")]
/**
* A String to keep track of the text changed as
* a result of user interaction.
*/
public function get typedText():String
{
return _typedText;
}
/**
* @private
*/
public function set typedText(input:String):void
{
_typedText = input;
typedTextChanged = true;
invalidateProperties();
invalidateDisplayList();
dispatchEvent(new Event("typedTextChange"));
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* @private
*/
override protected function commitProperties():void
{
super.commitProperties();
if(!dropdown)
selectedIndex=-1;
if(dropdown)
{
if(typedTextChanged)
{
cursorPosition = textInput.selectionActivePosition;//mansoor change: selectionBeginIndex;
updateDataProvider();
//In case there are no suggestions there is no need to show the dropdown
if(collection.length==0 || typedText==""|| typedText==null)
{
dropdownClosed=true;
showDropdown=false;
}
else
{
showDropdown = true;
selectedIndex = 0;
}
}
}
}
/**
* @private
*/
override protected function focusOutHandler(event:FocusEvent):void
{
super.focusOutHandler(event)
if(keepLocalHistory && dataProvider.length==0)
addToLocalHistory();
}
/**
* @private
*/
override public function getStyle(styleProp:String):*
{
if(styleProp != "openDuration")
return super.getStyle(styleProp);
else
{
if(dropdownClosed)
return super.getStyle(styleProp);
else
return 0;
}
}
/**
* @private
*/
override protected function keyDownHandler(event:KeyboardEvent):void
{
super.keyDownHandler(event);
if(!event.ctrlKey)
{
//An UP "keydown" event on the top-most item in the drop-down
//or an ESCAPE "keydown" event should change the text in text
// field to original text
if(event.keyCode == Keyboard.UP && prevIndex==0)
{
textInput.text = _typedText;
textInput.selectRange(textInput.text.length, textInput.text.length);//mansoor: setSelection(textInput.text.length, textInput.text.length);
selectedIndex = -1;
}
else if(event.keyCode==Keyboard.ESCAPE && showingDropdown)
{
textInput.text = _typedText;
textInput.selectRange(textInput.text.length, textInput.text.length);// mansoor: setSelection(textInput.text.length, textInput.text.length);
showingDropdown = false;
dropdownClosed=true;
}
else if(event.keyCode == Keyboard.ENTER)
{
if(keepLocalHistory && dataProvider.length==0)
addToLocalHistory();
}
else if(lookAhead && event.keyCode == Keyboard.BACKSPACE
|| event.keyCode == Keyboard.DELETE)
removeHighlight = true;
}
else
if(event.ctrlKey && event.keyCode == Keyboard.UP)
dropdownClosed=true;
prevIndex = selectedIndex;
}
/**
* @private
*/
override protected function measure():void
{
super.measure();
measuredWidth = mx.core.UIComponent.DEFAULT_MEASURED_WIDTH;
}
/**
* @private
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
//An UP "keydown" event on the top-most item in the drop
//down list otherwise changes the text in the text field to ""
if(selectedIndex == -1)
textInput.text = typedText;
if(dropdown)
{
if(typedTextChanged)
{
//This is needed because a call to super.updateDisplayList() set the text
// in the textInput to "" and thus the value
//typed by the user losts
if(lookAhead && showDropdown && typedText!="" && !removeHighlight)
{
var label:String = itemToLabel(collection[0]);
var index:Number = label.toLowerCase().indexOf(_typedText.toLowerCase());
if(index==0)
{
textInput.text = _typedText+label.substr(_typedText.length);
textInput.selectRange(textInput.text.length,_typedText.length);//setSelection(textInput.text.length,_typedText.length);
}
else
{
textInput.text = _typedText;
textInput.selectRange(cursorPosition, cursorPosition);
removeHighlight = false;
}
}
else
{
textInput.text = _typedText;
textInput.selectRange(cursorPosition, cursorPosition);
removeHighlight = false;
}
typedTextChanged= false;
}
else if(typedText)
//Sets the selection when user navigates the suggestion list through
//arrows keys.
textInput.selectRange(_typedText.length,textInput.text.length);
}
if(showDropdown && !dropdown.visible)
{
//This is needed to control the open duration of the dropdown
super.open();
showDropdown = false;
showingDropdown = true;
if(dropdownClosed)
dropdownClosed=false;
}
}
/**
* @private
*/
override protected function textInput_changeHandler(event:Event):void
{
super.textInput_changeHandler(event);
//Stores the text typed by the user in a variable
typedText=text;
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* If keepLocalHistory is enabled, stores the text typed
* by the user in the local history on the client machine
*/
private function addToLocalHistory():void
{
if (id != null && id != "" && text != null && text != "")
{
var so:SharedObject = SharedObject.getLocal("AutoCompleteData");
var savedData : Array = so.data.suggestions;
//No shared object has been created so far
if (savedData == null)
savedData = new Array();
var i:Number=0;
var flag:Boolean=false;
//Check if this entry is there in the previously saved shared object data
for(i=0;i<savedData.length;i++)
if(savedData[i]==text)
{
flag=true;
break;
}
if(!flag)
{
//Also ensure it is not there in the dataProvider
for(i=0;i<collection.length;i++)
if(defaultFilterFunction(itemToLabel(ListCollectionView(collection).getItemAt(i)),text))
{
flag=true;
break;
}
}
if(!flag)
savedData.push(text);
so.data.suggestions = savedData;
//write the shared object in the .sol file
so.flush();
}
}
/**
* @private
*/
private function defaultFilterFunction(element:*, text:String):Boolean
{
var label:String = itemToLabel(element);
return (label.toLowerCase().substring(0,text.length) == text.toLowerCase());
}
/**
* @private
*/
private function templateFilterFunction(element:*):Boolean
{
var flag:Boolean=false;
if(filterFunction!=null)
flag=filterFunction(element,typedText);
return flag;
}
/**
* @private
* Updates the dataProvider used for showing suggestions
*/
private function updateDataProvider():void
{
dataProvider = tempCollection;
collection.filterFunction = templateFilterFunction;
collection.refresh();
//In case there are no suggestions, check there is something in the localHistory
if(collection.length==0 && keepLocalHistory)
{
var so:SharedObject = SharedObject.getLocal("AutoCompleteData");
usingLocalHistory = true;
dataProvider = so.data.suggestions;
usingLocalHistory = false;
collection.filterFunction = templateFilterFunction;
collection.refresh();
}
}
}
}
答案 0 :(得分:1)
Flash无法实现。您所能做的就是收听关键事件,而不是让用户正常写入,截取它并在所需位置添加按下的键的字符。
答案 1 :(得分:0)
有人可以查看完整的示例。组件演示 http://flashcommander.org/blog/flex-4-autocomplete