提供多单词建议的自定义AutoCompleteExtender

默认情况下,AutoCompleteExtender显示的结果来自于文本框中输入的全部值,这里我的实现,它可以去搜索文本框中多于一个的单词,它们之间用逗号分割(或者别的符号),任何时间输入逗号,将会显示一个新的建议下拉列表。AutoCompleteExtender并不支持这种类型的列表,我们将通过一些修改来实现这些属性。[英文原文来自于CodeProject]

 

主要内容

1.简介

2.继承AutoCompleteProperties

3.继承AutoCompleteExtender

4.实现自定义的AutoCompleteBehavior

5.测试

 

简介

默认情况下,AutoCompleteExtender显示的结果来自于文本框中输入的全部值,这里我的实现,它可以去搜索文本框中多于一个的单词,它们之间用逗号分割(或者别的符号),任何时间输入逗号,将会显示一个新的建议下拉列表。AutoCompleteExtender并不支持这种类型的列表,我们将通过一些修改来实现这些属性。

 

继承AutoCompleteProperties

第一步为新控件CustomAutoCompleteExtender创建C#类,我们将定义一个继承于AutoCompleteProperties的类CustomAutoCompleteProperties,并添加多单词建议支持和CSS样式属性,为了实现多单词建议,我们需要一个属性SeparatorChar,通过该属性,我们可以拆分成一个一个的单词并为最新输入的单词打开建议列表。

None.gif namespace  CustomAtlas.Controls
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    
public class CustomAutoCompleteProperties : AutoCompleteProperties
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
public string SeparatorChar
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
object obj = base.ViewState["SeparatorChar"];
InBlock.gif
InBlock.gif                
if (obj != nullreturn (string)obj;
InBlock.gif
InBlock.gif                
else return ",";
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
base.ViewState["SeparatorChar"= value;
InBlock.gif
InBlock.gif                
base.OnChanged(EventArgs.Empty);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
public string CssList
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
object obj = base.ViewState["CssList"];
InBlock.gif
InBlock.gif                
if (obj != nullreturn (string)obj;
InBlock.gif
InBlock.gif                
else return String.Empty;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
base.ViewState["CssList"= value;
InBlock.gif
InBlock.gif                
base.OnChanged(EventArgs.Empty);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
public string CssItem
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
object obj = base.ViewState["CssItem"];
InBlock.gif
InBlock.gif                
if (obj != nullreturn (string)obj;
InBlock.gif
InBlock.gif                
else return String.Empty;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
base.ViewState["CssItem"= value;
InBlock.gif
InBlock.gif                
base.OnChanged(EventArgs.Empty);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        
public string CssHoverItem
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
get
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
object obj = base.ViewState["CssHoverItem"];
InBlock.gif
InBlock.gif                
if (obj != nullreturn (string)obj;
InBlock.gif
InBlock.gif                
else return String.Empty;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
set
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
base.ViewState["CssHoverItem"= value;
InBlock.gif
InBlock.gif                
base.OnChanged(EventArgs.Empty);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

CssList, CssItemCssHoverItem需要构建控件的样式,CssList提供用来画下拉列表,CssItemCssHoverItem用来画列表中的每一项。

 

继承AutoCompleteExtender

完成了第一步,我们继续实现Extender,在这里我们需要从AutoCompleteExtender继承并为控件添加新的属性。

None.gif namespace  CustomAtlas.Controls
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif    
public class CustomAutoCompleteExtender : AutoCompleteExtender
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
protected override void RenderScript(Microsoft.Web.Script.ScriptTextWriter writer, Control targetControl)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
// get our CustomAutoCompleteProperties
InBlock.gif

InBlock.gif            CustomAutoCompleteProperties cacp 
= (CustomAutoCompleteProperties) base.GetTargetProperties(targetControl);
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif            
if ((cacp != null&& cacp.Enabled)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
// check if the ServicePath is set
InBlock.gif

InBlock.gif                
string _ServicePath = cacp.ServicePath;
InBlock.gif
InBlock.gif                
if (_ServicePath == String.Empty)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    _ServicePath 
= this.ServicePath;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
if (_ServicePath == String.Empty)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    
throw new InvalidOperationException("The ServicePath must be set for AutoCompleteBehavior");
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif                
// check if the ServiceMethod is set
InBlock.gif

InBlock.gif                
string _ServiceMethod = cacp.ServiceMethod;
InBlock.gif
InBlock.gif                
if (_ServiceMethod == String.Empty)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    _ServiceMethod 
= this.ServiceMethod;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
if (_ServiceMethod == String.Empty)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    
throw new InvalidOperationException("The ServiceMethod must be set for AutoCompleteBehavior");
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif                
// search for the completion list control if an ID was supplied
InBlock.gif

InBlock.gif                Control c 
= null;
InBlock.gif
InBlock.gif                
string drp = this.DropDownPanelID;
InBlock.gif
InBlock.gif                
if (drp != String.Empty)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    c 
= this.NamingContainer.FindControl(drp);
InBlock.gif
InBlock.gif                    
if (c == null)
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif
InBlock.gif                        
throw new InvalidOperationException("The specified DropDownPanelID is not a valid ID");
InBlock.gif
ExpandedSubBlockEnd.gif                    }

InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif                
// write the Atlas markup on page
InBlock.gif

InBlock.gif                writer.WriteStartElement(
"autoComplete");
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"serviceURL"base.ResolveClientUrl(_ServicePath));
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"serviceMethod", _ServiceMethod);
InBlock.gif
InBlock.gif                
if (c != null) writer.WriteAttributeString("completionList", c.ClientID);
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"minimumPrefixLength", cacp.MinimumPrefixLength.ToString());
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"separatorChar", cacp.SeparatorChar);
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"cssList", cacp.CssList);
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"cssItem", cacp.CssItem);
InBlock.gif
InBlock.gif                writer.WriteAttributeString(
"cssHoverItem", cacp.CssHoverItem);
InBlock.gif
InBlock.gif                writer.WriteEndElement();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

 

实现自定义的AutoCompleteBehavior

现在控件已经完成,我们只剩下管理客户端代码以发送正确的值到WebService并提供我们自定义的CSS样式。在Atlas.js中查找到AutoCompleteBehavior,我们可以拷贝到这里并注册我们自己的类。

None.gif ype.registerNamespace('Custom.UI');
None.gif
None.gif 
None.gif
ExpandedBlockStart.gifContractedBlock.gifCustom.UI.AutoCompleteBehavior 
=   function ()  dot.gif {
InBlock.gif
InBlock.gif    Custom.UI.AutoCompleteBehavior.initializeBase(
this);
InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif    
var _appURL;
InBlock.gif
InBlock.gif    
var _serviceURL;
InBlock.gif
InBlock.gif    
var _serviceMethod;
InBlock.gif
InBlock.gif    
var _separatorChar = ',';
InBlock.gif
InBlock.gif    
var _minimumPrefixLength = 3;
InBlock.gif
InBlock.gif    
var _cssList;
InBlock.gif
InBlock.gif    
var _cssItem;
InBlock.gif
InBlock.gif    
var _cssHoverItem;
InBlock.gif
InBlock.gif    
var _completionSetCount = 10;
InBlock.gif
InBlock.gif    
var _completionInterval = 1000;
InBlock.gif
InBlock.gif    
var _completionListElement;
InBlock.gif
InBlock.gif    
var _popupBehavior;
InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif    
var _timer;
InBlock.gif
InBlock.gif    
var _cache;
InBlock.gif
InBlock.gif    
var _currentPrefix;
InBlock.gif
InBlock.gif    
var _selectIndex;
InBlock.gif
InBlock.gif    
InBlock.gif
InBlock.gif    
var _focusHandler;
InBlock.gif
InBlock.gif    
var _blurHandler;
InBlock.gif
InBlock.gif    
var _keyDownHandler;
InBlock.gif
InBlock.gif    
var _mouseDownHandler;
InBlock.gif
InBlock.gif    
var _mouseUpHandler;
InBlock.gif
InBlock.gif    
var _mouseOverHandler;
InBlock.gif
InBlock.gif    
var _tickHandler;
InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_appURL = function() dot.gif{
InBlock.gif
InBlock.gif        
return _appURL;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_appURL = function(value) dot.gif{
InBlock.gif
InBlock.gif        _appURL 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_completionInterval = function() dot.gif{
InBlock.gif
InBlock.gif        
return _completionInterval;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_completionInterval = function(value) dot.gif{
InBlock.gif
InBlock.gif        _completionInterval 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_completionList = function() dot.gif{
InBlock.gif
InBlock.gif        
return _completionListElement;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_completionList = function(value) dot.gif{
InBlock.gif
InBlock.gif        _completionListElement 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_completionSetCount = function() dot.gif{
InBlock.gif
InBlock.gif        
return _completionSetCount;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_completionSetCount = function(value) dot.gif{
InBlock.gif
InBlock.gif        _completionSetCount 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_minimumPrefixLength = function() dot.gif{
InBlock.gif
InBlock.gif        
return _minimumPrefixLength;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_minimumPrefixLength = function(value) dot.gif{
InBlock.gif
InBlock.gif        _minimumPrefixLength 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_separatorChar = function() dot.gif{
InBlock.gif
InBlock.gif        
return _separatorChar;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_separatorChar = function(value) dot.gif{
InBlock.gif
InBlock.gif        _separatorChar 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_serviceMethod = function() dot.gif{
InBlock.gif
InBlock.gif        
return _serviceMethod;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_serviceMethod = function(value) dot.gif{
InBlock.gif
InBlock.gif        _serviceMethod 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_serviceURL = function() dot.gif{
InBlock.gif
InBlock.gif        
return _serviceURL;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_serviceURL = function(value) dot.gif{
InBlock.gif
InBlock.gif        _serviceURL 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//* styles */
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_cssList = function() dot.gif{
InBlock.gif
InBlock.gif        
return _cssList;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_cssList = function(value) dot.gif{
InBlock.gif
InBlock.gif        _cssList 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_cssItem = function() dot.gif{
InBlock.gif
InBlock.gif        
return _cssItem;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_cssItem = function(value) dot.gif{
InBlock.gif
InBlock.gif        _cssItem 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.get_cssHoverItem = function() dot.gif{
InBlock.gif
InBlock.gif        
return _cssHoverItem;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.set_cssHoverItem = function(value) dot.gif{
InBlock.gif
InBlock.gif        _cssHoverItem 
= value;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.dispose = function() dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (_timer) dot.gif{
InBlock.gif
InBlock.gif            _timer.tick.remove(_tickHandler);
InBlock.gif
InBlock.gif            _timer.dispose();
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
var element = this.control.element;
InBlock.gif
InBlock.gif        element.detachEvent('onfocus', _focusHandler);
InBlock.gif
InBlock.gif        element.detachEvent('onblur', _blurHandler);
InBlock.gif
InBlock.gif        element.detachEvent('onkeydown', _keyDownHandler);
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        _completionListElement.detachEvent('onmousedown', _mouseDownHandler);
InBlock.gif
InBlock.gif        _completionListElement.detachEvent('onmouseup', _mouseUpHandler);
InBlock.gif
InBlock.gif        _completionListElement.detachEvent('onmouseover', _mouseOverHandler);
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        _tickHandler 
= null;
InBlock.gif
InBlock.gif        _focusHandler 
= null;
InBlock.gif
InBlock.gif        _blurHandler 
= null;
InBlock.gif
InBlock.gif        _keyDownHandler 
= null;
InBlock.gif
InBlock.gif        _mouseDownHandler 
= null;
InBlock.gif
InBlock.gif        _mouseUpHandler 
= null;
InBlock.gif
InBlock.gif        _mouseOverHandler 
= null;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        Sys.UI.AutoCompleteBehavior.callBaseMethod(
this, 'dispose');
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.getDescriptor = function() dot.gif{
InBlock.gif
InBlock.gif        
var td = Custom.UI.AutoCompleteBehavior.callBaseMethod(this, 'getDescriptor');
InBlock.gif
InBlock.gif        td.addProperty('completionInterval', Number);
InBlock.gif
InBlock.gif        td.addProperty('completionList', Object, 
false, Sys.Attributes.Element, true);
InBlock.gif
InBlock.gif        td.addProperty('completionSetCount', Number);
InBlock.gif
InBlock.gif        td.addProperty('minimumPrefixLength', Number);
InBlock.gif
InBlock.gif        td.addProperty('separatorChar', String);
InBlock.gif
InBlock.gif        td.addProperty('cssList', String);
InBlock.gif
InBlock.gif        td.addProperty('cssItem', String);
InBlock.gif
InBlock.gif        td.addProperty('cssHoverItem', String);
InBlock.gif
InBlock.gif        td.addProperty('serviceMethod', String);
InBlock.gif
InBlock.gif        td.addProperty('serviceURL', String);
InBlock.gif
InBlock.gif        td.addProperty('appURL', String);
InBlock.gif
InBlock.gif        
return td;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this.initialize = function() dot.gif{
InBlock.gif
InBlock.gif        Custom.UI.AutoCompleteBehavior.callBaseMethod(
this, 'initialize');
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        _tickHandler 
= Function.createDelegate(thisthis._onTimerTick);
InBlock.gif
InBlock.gif        _focusHandler 
= Function.createDelegate(thisthis._onGotFocus);
InBlock.gif
InBlock.gif        _blurHandler 
= Function.createDelegate(thisthis._onLostFocus);
InBlock.gif
InBlock.gif        _keyDownHandler 
= Function.createDelegate(thisthis._onKeyDown);
InBlock.gif
InBlock.gif        _mouseDownHandler 
= Function.createDelegate(thisthis._onListMouseDown);
InBlock.gif
InBlock.gif        _mouseUpHandler 
= Function.createDelegate(thisthis._onListMouseUp);
InBlock.gif
InBlock.gif        _mouseOverHandler 
= Function.createDelegate(thisthis._onListMouseOver);
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        _timer 
= new Sys.Timer();
InBlock.gif
InBlock.gif        _timer.set_interval(_completionInterval);
InBlock.gif
InBlock.gif        _timer.tick.add(_tickHandler);
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
var element = this.control.element;
InBlock.gif
InBlock.gif        element.autocomplete 
= "off";
InBlock.gif
InBlock.gif        element.attachEvent('onfocus', _focusHandler);
InBlock.gif
InBlock.gif        element.attachEvent('onblur', _blurHandler);
InBlock.gif
InBlock.gif        element.attachEvent('onkeydown', _keyDownHandler);
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
var elementBounds = Sys.UI.Control.getBounds(element);
InBlock.gif
InBlock.gif        
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (!_completionListElement) dot.gif{
InBlock.gif
InBlock.gif            _completionListElement 
= document.createElement('DIV');
InBlock.gif
InBlock.gif            document.body.appendChild(_completionListElement);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        
// apply styles
InBlock.gif

InBlock.gif        
var completionListStyle = _completionListElement.style;
InBlock.gif
InBlock.gif        
if ( _cssList != '' ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            _completionListElement.className 
= _cssList;
InBlock.gif
ExpandedSubBlockEnd.gif        }
 
InBlock.gif
InBlock.gif        
else 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            completionListStyle.backgroundColor 
= 'window';
InBlock.gif
InBlock.gif            completionListStyle.color 
= 'windowtext';
InBlock.gif
InBlock.gif            completionListStyle.border 
= 'solid 1px buttonshadow';
InBlock.gif
InBlock.gif            completionListStyle.cursor 
= 'default';
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// default styles
InBlock.gif

InBlock.gif        completionListStyle.unselectable 
= 'unselectable';
InBlock.gif
InBlock.gif        completionListStyle.overflow 
= 'hidden';
InBlock.gif
InBlock.gif        completionListStyle.visibility 
= 'hidden';
InBlock.gif
InBlock.gif        completionListStyle.width 
= (elementBounds.width - 2+ 'px';
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif        _completionListElement.attachEvent('onmousedown', _mouseDownHandler);
InBlock.gif
InBlock.gif        _completionListElement.attachEvent('onmouseup', _mouseUpHandler);
InBlock.gif
InBlock.gif        _completionListElement.attachEvent('onmouseover', _mouseOverHandler);
InBlock.gif
InBlock.gif        document.body.appendChild(_completionListElement);
InBlock.gif
InBlock.gif        
var popupControl = new Sys.UI.Control(_completionListElement);
InBlock.gif
InBlock.gif        _popupBehavior 
= new Sys.UI.PopupBehavior();
InBlock.gif
InBlock.gif        _popupBehavior.set_parentElement(element);
InBlock.gif
InBlock.gif        _popupBehavior.set_positioningMode(Sys.UI.PositioningMode.BottomLeft);
InBlock.gif
InBlock.gif        popupControl.get_behaviors().add(_popupBehavior);
InBlock.gif
InBlock.gif        _popupBehavior.initialize();
InBlock.gif
InBlock.gif        popupControl.initialize();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._hideCompletionList = function() dot.gif{
InBlock.gif
InBlock.gif        _popupBehavior.hide();
InBlock.gif
InBlock.gif        _completionListElement.innerHTML 
= '';
InBlock.gif
InBlock.gif        _selectIndex 
= -1;
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._highlightItem = function(item) dot.gif{
InBlock.gif
InBlock.gif        
var children = _completionListElement.childNodes;
InBlock.gif
InBlock.gif        
// non-selecteditems
InBlock.gif

ExpandedSubBlockStart.gifContractedSubBlock.gif        
for (var i = 0; i < children.length; i++dot.gif{
InBlock.gif
InBlock.gif            
var child = children[i];
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (child != item) dot.gif{
InBlock.gif
InBlock.gif                
if ( _cssItem != '' ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    child.className 
= _cssItem;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
else
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    child.style.backgroundColor 
= 'window';
InBlock.gif
InBlock.gif                    child.style.color 
= 'windowtext';
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// selected item
InBlock.gif

InBlock.gif        
if ( _cssHoverItem != '' ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            item.className 
= _cssHoverItem;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
else 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            item.style.backgroundColor 
= 'highlight';
InBlock.gif
InBlock.gif            item.style.color 
= 'highlighttext';
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onListMouseDown = function() dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (window.event.srcElement != _completionListElement) dot.gif{
InBlock.gif
InBlock.gif            
this._setText(window.event.srcElement.firstChild.nodeValue);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onListMouseUp = function() dot.gif{
InBlock.gif
InBlock.gif        
this.control.focus();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onListMouseOver = function() dot.gif{
InBlock.gif
InBlock.gif        
var item = window.event.srcElement;
InBlock.gif
InBlock.gif        _selectIndex 
= -1;
InBlock.gif
InBlock.gif        
this._highlightItem(item);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onGotFocus = function() dot.gif{
InBlock.gif
InBlock.gif        _timer.set_enabled(
true);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onKeyDown = function() dot.gif{
InBlock.gif
InBlock.gif        
var e = window.event;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (e.keyCode == 27dot.gif{
InBlock.gif
InBlock.gif            
this._hideCompletionList();
InBlock.gif
InBlock.gif            e.returnValue 
= false;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else if (e.keyCode == Sys.UI.Key.Up) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (_selectIndex > 0dot.gif{
InBlock.gif
InBlock.gif                _selectIndex
--;
InBlock.gif
InBlock.gif                
this._highlightItem(_completionListElement.childNodes[_selectIndex]);
InBlock.gif
InBlock.gif                e.returnValue 
= false;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else if (e.keyCode == Sys.UI.Key.Down) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (_selectIndex < (_completionListElement.childNodes.length - 1)) dot.gif{
InBlock.gif
InBlock.gif                _selectIndex
++;
InBlock.gif
InBlock.gif                
this._highlightItem(_completionListElement.childNodes[_selectIndex]);
InBlock.gif
InBlock.gif                e.returnValue 
= false;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else if (e.keyCode == Sys.UI.Key.Return) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (_selectIndex != -1dot.gif{
InBlock.gif
InBlock.gif                
this._setText(_completionListElement.childNodes[_selectIndex].firstChild.nodeValue);
InBlock.gif
InBlock.gif                e.returnValue 
= false;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (e.keyCode != Sys.UI.Key.Tab) dot.gif{
InBlock.gif
InBlock.gif            _timer.set_enabled(
true);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onLostFocus = function() dot.gif{
InBlock.gif
InBlock.gif        _timer.set_enabled(
false);
InBlock.gif
InBlock.gif        
this._hideCompletionList();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
function _onMethodComplete(result, response, context) dot.gif{
InBlock.gif
InBlock.gif        
var acBehavior = context[0];
InBlock.gif
InBlock.gif        
var prefixText = context[1];
InBlock.gif
InBlock.gif        acBehavior._update(prefixText, result,  
true);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._onTimerTick = function(sender, eventArgs) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (_serviceURL && _serviceMethod) dot.gif{
InBlock.gif
InBlock.gif        
InBlock.gif
InBlock.gif            
var text = this.control.element.value;
InBlock.gif
InBlock.gif            
InBlock.gif
InBlock.gif            
if ( text.lastIndexOf(_separatorChar) > -1 ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
// found separator char in the text
InBlock.gif

InBlock.gif                
var pos = text.lastIndexOf(_separatorChar);
InBlock.gif
InBlock.gif                pos
++;
InBlock.gif
InBlock.gif                text 
= text.substring(pos, (text.length));
InBlock.gif
InBlock.gif                text 
= text.trim();
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (text.trim().length < _minimumPrefixLength) dot.gif{
InBlock.gif
InBlock.gif                
this._update('', null,  false);
InBlock.gif
InBlock.gif                
return;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (_currentPrefix != text) dot.gif{
InBlock.gif
InBlock.gif                _currentPrefix 
= text;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
if (_cache && _cache[text]) dot.gif{
InBlock.gif
InBlock.gif                    
this._update(text, _cache[text],  false);
InBlock.gif
InBlock.gif                    
return;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
InBlock.gif
InBlock.gif                Sys.Net.ServiceMethod.invoke(_serviceURL, _serviceMethod, _appURL,
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                                                          
dot.gif{ prefixText : _currentPrefix, count: _completionSetCount },
InBlock.gif
InBlock.gif                                                          _onMethodComplete, 
nullnullnull,
InBlock.gif
InBlock.gif                                                          [ 
this, text ]);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._setText = function(text) dot.gif{
InBlock.gif
InBlock.gif        _timer.set_enabled(
false);
InBlock.gif
InBlock.gif        _currentPrefix 
= text;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (Sys.UI.TextBox.isInstanceOfType(this.control)) dot.gif{
InBlock.gif
InBlock.gif            
this.control.set_text(text);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else dot.gif{
InBlock.gif
InBlock.gif            
var currentValue = this.control.element.value;
InBlock.gif
InBlock.gif            
if ( currentValue.lastIndexOf(_separatorChar) > -1 ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
// found separator char in the text
InBlock.gif

InBlock.gif                
var pos = currentValue.lastIndexOf(_separatorChar);
InBlock.gif
InBlock.gif                pos
++;
InBlock.gif
InBlock.gif                currentValue 
= currentValue.substring(0, pos) + text;
InBlock.gif
ExpandedSubBlockEnd.gif            }
 
InBlock.gif
InBlock.gif            
else 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif
InBlock.gif                
// no separator char found
InBlock.gif

InBlock.gif                currentValue 
= text;
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
this.control.element.value = currentValue;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
this._hideCompletionList();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
this._update = function(prefixText, completionItems, cacheResults) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (cacheResults) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if (!_cache) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                _cache 
= dot.gif{ };
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            _cache[prefixText] 
= completionItems;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        _completionListElement.innerHTML 
= '';
InBlock.gif
InBlock.gif        _selectIndex 
= -1;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (completionItems && completionItems.length) dot.gif{
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif            
for (var i = 0; i < completionItems.length; i++dot.gif{
InBlock.gif
InBlock.gif                
var itemElement = document.createElement('div');
InBlock.gif
InBlock.gif                itemElement.appendChild(document.createTextNode(completionItems[i]));
InBlock.gif
InBlock.gif                itemElement.__item 
= '';
InBlock.gif
InBlock.gif                
if ( _cssItem != '' ) 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif
InBlock.gif                    itemElement.className 
= _cssItem;
InBlock.gif
ExpandedSubBlockEnd.gif                }

InBlock.gif
InBlock.gif                
else
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{                
InBlock.gif
InBlock.gif                    
var itemElementStyle = itemElement.style;
InBlock.gif
InBlock.gif                    itemElementStyle.padding 
= '1px';
InBlock.gif
InBlock.gif                    itemElementStyle.textAlign 
= 'left';
InBlock.gif
InBlock.gif                    itemElementStyle.textOverflow 
= 'ellipsis';
InBlock.gif
InBlock.gif                    itemElementStyle.backgroundColor 
= 'window';
InBlock.gif
InBlock.gif                    itemElementStyle.color 
= 'windowtext';
InBlock.gif
ExpandedSubBlockEnd.gif                }
                
InBlock.gif
InBlock.gif                _completionListElement.appendChild(itemElement);
InBlock.gif
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            _popupBehavior.show();
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
else dot.gif{
InBlock.gif
InBlock.gif            _popupBehavior.hide();
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gifCustom.UI.AutoCompleteBehavior.registerSealedClass('Custom.UI.AutoCompleteBehavior', Sys.UI.Behavior);
None.gif
None.gifSys.TypeDescriptor.addType('script', 'autoComplete', Custom.UI.AutoCompleteBehavior);

首先我们在Extender类中添加了四个已经创建的属性,现在我们可以在.aspx页面中使用这些属性的值。

在代码中找到函数_onTimerTick,它用来延迟显示下拉列表,在该函数中,我们可以发送该值到WebService,如果需要我们也可以改变它的值。

None.gif var  text  =   this .control.element.value;
None.gif
None.gif
if  ( text.lastIndexOf(_separatorChar)  >   - 1  ) 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
InBlock.gif 
// found separator char in the text, choosing the right word
InBlock.gif

InBlock.gif 
var pos = text.lastIndexOf(_separatorChar);
InBlock.gif
InBlock.gif pos
++;
InBlock.gif
InBlock.gif text 
= text.substring(pos, (text.length));
InBlock.gif
InBlock.giftext 
= text.trim();
InBlock.gif
ExpandedBlockEnd.gif}

现在,无论用户何时在文本框中输入一个值,AutoCompleteBehavior会验证驻留的分割字符,找到最后一个单词或者TextBox中的全部文本发送到WebService

 

测试

解决方案:AutoCompleteBehavior.js保存在scriptLibrary文件夹下,CustomAutoCompleteProperties.cs CustomAutoCompleteExtender.cs保存在App_Code文件夹下。

创建一个新的.aspx文件,并且添加对CustomAutoCompleteExtender类的引用,并在页面中放一些控件:

ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif @ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"  %>
None.gif
ExpandedBlockStart.gifContractedBlock.gif
<% dot.gif @ Register Namespace="CustomAtlas.Controls" TagPrefix="customAtlas"  %>
None.gif
None.gif 
None.gif
None.gif
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
None.gif
None.gif
< html  xmlns ="http://www.w3.org/1999/xhtml" >
None.gif
None.gif
< head  runat ="server" >
None.gif
None.gif    
< title > CustomAutoCompleteExtender </ title >
None.gif
None.gif    
< link  href ="StyleSheet.css"  rel ="stylesheet"  type ="text/css"   />
None.gif
None.gif
</ head >
None.gif
None.gif
< body >
None.gif
None.gif    
< form  id ="form1"  runat ="server" >
None.gif
None.gif        
< atlas:ScriptManager  ID ="scriptManager"  runat ="server" >
None.gif
ExpandedBlockStart.gifContractedBlock.gif            
< Scripts > dot.gif
InBlock.gif
InBlock.gif                
<atlas:ScriptReference ScriptName="Custom" />
InBlock.gif
InBlock.gif                
<atlas:ScriptReference Path="scriptLibrary/CustomAutoCompleteBehavior.js" />
InBlock.gif
ExpandedBlockEnd.gif            
</ Scripts >
None.gif
None.gif        
</ atlas:ScriptManager >
None.gif
None.gif        
None.gif
None.gif        
< div >
None.gif
None.gif            
< asp:TextBox  ID ="txtSuggestions"  runat ="server" ></ asp:TextBox >
None.gif
None.gif            
< customAtlas:CustomAutoCompleteExtender  ID ="CustomAutoCompleteExtender1"  runat ="server" >
None.gif
None.gif                
< customAtlas:CustomAutoCompleteProperties
None.gif
None.gif                                 
TargetControlID ="txtSuggestions"
None.gif
None.gif                                 ServicePath
="WebServiceDemo.asmx"
None.gif
None.gif                                 ServiceMethod
="GetSuggestions"
None.gif
None.gif                                 MinimumPrefixLength
="1"
None.gif
None.gif                                 SeparatorChar
=","
None.gif
None.gif                                 CssList
="autoCompleteList"
None.gif
None.gif                                 CssItem
="autoCompleteItem"  
None.gif
None.gif                                 CssHoverItem
="autoCompleteHoverItem"
None.gif
None.gif                                 Enabled
="true"   />
None.gif
None.gif            
</ customAtlas:CustomAutoCompleteExtender >        
None.gif
None.gif        
</ div >
None.gif
None.gif    
</ form >
None.gif
None.gif
</ body >
None.gif
None.gif
</ html >

调用一个简单的示例WebService,输入一个单词,再输入逗号(逗号是默认值),并重新输入一个新的单词,将会显示出一个新的建议下拉列表。显示效果如下:

希望对你有所帮助!

原文地址:http://www.codeproject.com/Ajax/CustomAutoCompleteExt.asp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值