默认情况下,AutoCompleteExtender不支持这种行为,但您可以调整AutoCompleteExtender源代码以添加此功能。实际上有两种可用的方法:第一种是扩展从Web服务返回到Extender的对象,并使用新属性来应用项目CSS类,然后在Extender客户端脚本中应用该属性值。第二种可用的方法是引入新的项目创建事件,在页面上处理它并根据其值对项目应用自定义逻辑。让我们在这里实现这两种方法。首先,如果您还没有下载AjaxControlToolkit源代码,请下载并打开
Client/MicrosoftAjax.Extended/AutoComplete/AutoCompleteBehavior.pre.js
文件。在这个文件中,您需要更改
_update
方法如下所示:
_update: function (prefixText, completionItems, cacheResults) {
if (cacheResults && this.get_enableCaching()) {
if (!this._cache) {
this._cache = {};
}
this._cache[prefixText] = completionItems;
}
if ((!this._textBoxHasFocus) || (prefixText != this._currentCompletionWord())) {
this._hideCompletionList();
return;
}
if (completionItems && completionItems.length) {
this._completionListElement.innerHTML = '';
this._selectIndex = -1;
var _firstChild = null;
var text = null;
var value = null;
var cssClass = null;
var dataItem = null;
var itemDataBindingHandler = this.get_events().getHandler('itemDataBinding');
for (var i = 0; i < completionItems.length; i++) {
var itemElement = null;
if (this._completionListElementID) {
itemElement = document.createElement('div');
} else {
itemElement = document.createElement('li');
}
if (_firstChild == null) {
_firstChild = itemElement;
}
try {
dataItem = Sys.Serialization.JavaScriptSerializer.deserialize( completionItems[i] );
if (dataItem && dataItem.First) {
text = dataItem.First;
value = dataItem.Second;
if (dataItem.CssClass) {
cssClass = dataItem.CssClass;
}
}
else {
text = completionItems[i];
value = text;
}
} catch (ex) {
text = completionItems[i];
value = completionItems[i];
}
var optionText = this._showOnlyCurrentWordInCompletionListItem ? text : this._getTextWithInsertedWord(text);
itemElement.appendChild(document.createTextNode(optionText));
itemElement._value = value;
itemElement.__item = '';
if (this._completionListItemCssClass) {
Sys.UI.DomElement.addCssClass(itemElement, this._completionListItemCssClass);
} else {
var itemElementStyle = itemElement.style;
itemElementStyle.padding = '0px';
itemElementStyle.textAlign = 'left';
itemElementStyle.textOverflow = 'ellipsis';
if (Sys.Browser.agent === Sys.Browser.Safari) {
itemElementStyle.backgroundColor = 'white';
itemElementStyle.color = 'black';
} else {
itemElementStyle.backgroundColor = this._textBackground;
itemElementStyle.color = this._textColor;
}
}
if (cssClass) {
Sys.UI.DomElement.addCssClass(itemElement, cssClass);
}
if (itemDataBindingHandler) {
itemDataBindingHandler(itemElement, dataItem || completionItems[i]);
}
this._completionListElement.appendChild(itemElement);
}
var elementBounds = $common.getBounds(this.get_element());
this._completionListElement.style.width = Math.max(1, elementBounds.width - 2) + 'px';
this._completionListElement.scrollTop = 0;
this.raisePopulated(Sys.EventArgs.Empty);
var eventArgs = new Sys.CancelEventArgs();
this.raiseShowing(eventArgs);
if (!eventArgs.get_cancel()) {
this.showPopup();
if (this._firstRowSelected && (_firstChild != null)) {
this._highlightItem(_firstChild);
this._selectIndex = 0;
}
}
} else {
this._hideCompletionList();
}
}
如果您不打算实现新的客户端事件场景,那么您需要的项目更改就是这些。您已经可以从Web服务器方法中传递项目的CSS类、文本和值。唯一的区别是要使用自定义类,而不是AjaxControlToolkit控件默认使用的Pair类:
[WebMethod]
public string[] GetCompletionList(string prefixText, int count)
{
var serializer = new JavaScriptSerializer();
var items = Enumerable.Range(1, count)
.Select(id => serializer.Serialize(
new
{
Second = id,
First = prefixText + "_" + Guid.NewGuid().ToString(),
CssClass = id % 2 == 0 ? "even" : "odd"
}));
return items.ToArray();
}
如果您想要实现自定义客户端事件(确实可以增加更多的灵活性),那么您需要在AutoCompleteBehavior.pre.js文件中添加一些代码。 在Sys.Extended.UI.AutoCompleteBehavior.prototype对象中的某个位置添加以下代码:
add_itemDataBinding: function (handler) {
this.get_events().addHandler('itemDataBinding', handler);
},
remove_itemDataBinding: function (handler) {
this.get_events().removeHandler('itemDataBinding', handler);
},
同时,打开
Server/AjaxControlToolkit/AutoComplete/AutoCompleteExtender.cs
文件,并将此属性添加到AutoCompleteExtender类中:
[DefaultValue("")]
[ExtenderControlEvent]
[ClientPropertyName("itemDataBinding")]
public string OnClientItemDataBinding
{
get { return GetPropertyValue("OnClientItemDataBinding", string.Empty); }
set { SetPropertyValue("OnClientItemDataBinding", value); }
}
重新构建项目后,您可以使用具有额外功能的自定义AjaxControlToolkit程序集。
<script type="text/javascript">
function itemDataBinding(item, dataItem) {
var value = parseInt(dataItem.Second, 10);
if (!isNaN(value)) {
item.className = value % 2 == 0 ? "even" : "odd";
}
}
</script>
<ajaxToolkit:AutoCompleteExtender runat="server" ID="autoComplete1"
TargetControlID="myTextBox" ServicePath="AutoComplete.asmx" ServiceMethod="GetCompletionList"
OnClientItemDataBinding="itemDataBinding">