AjaxControlToolKit环境下用UserControl(C#)模拟的自定义下拉框SELDropDownList
用Asp.net UserControl实现的样式可控的DropDownList
在上一篇文章《AjaxControlToolkit环境下用Javascript实现简单的Dropdownlist 》里写了关于用javascript写的一个dropdownlist的例子,由于不易于复用和在C#里进行管理,所以后来用UserControl重新封装了一个DropDownList控件,基本模拟Asp.Net原有的DropDownList控件,使得其他用户直接托拽到相应地方即可正常工作。
首先还是先看一下截图:
实现过程如下:
1、Aspx代码部分:
用div及textbox等模拟相应的文字框和下拉框,并在Sys.Application.init时创建对应的SELDropDownListBehavior。
SELDropDownList.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SELDropDownList.ascx.cs"
Inherits="DropdownlistUserControl.SELDropDownList" %>
<script language="javascript">
var <% =this.ClientID %>_Instance = null;
Sys.Application.add_init(
function(){
<% =this.ClientID %>_Instance = new SELDropDownListBehavior(
{
// Elements
"GlobalContainer" : $get("<%=this.ClientID %>"),
"HeaderContainer" : $get("<% = header.ClientID %>"),
"HeaderText" : $get("<% = headerText.ClientID %>"),
"ArrowImage" : $get("<% = arrowImage.ClientID %>"),
"ListBox" : $get("<% = listBox.ClientID %>"),
"SelectedIndexField" : $get("<% = hdnSelectedIndex.ClientID %>"),
// Properties
"ArrowImageUrl" : "<%=ArrowImageUrl%>",
"ArrowImageHoverUrl" : "<%=ArrowImageHoverUrl %>",
"AutoPostBack" : <%=AutoPostBack.ToString().ToLower() %>,
"SelectedIndexChangeClientScript" : "<%=SelectedIndexChangeClientScript%>",
"DoPostBackElementID" : "<%=lbtnDoPostBack.ClientID%>",
// CSS
"ItemCssClass" : "<%= ItemCssClass %>",
"ItemHoverCssClass" : "<%= ItemHoverCssClass %>",
"ItemAlternateCssClass" : "<%= ItemAlternateCssClass %>",
"ItemAlternateHoverCssClass" : "<%= ItemAlternateHoverCssClass %>",
"ItemSelectedCssClass" : "<%= ItemSelectedCssClass %>",
"ItemSelectedHoverCssClass" : "<%= ItemSelectedHoverCssClass %>"
}
);
// Set the options and selectedIndex
var <% =this.ClientID %>_DropDownList = $get("<% =this.ClientID %>");
<% =this.ClientID %>_DropDownList.options = <%=GetOptionsForClient() %>;
<% =this.ClientID %>_DropDownList.selectedIndex =
{
valueOf : function()
{
if( <% =this.ClientID %>_Instance )
return <% =this.ClientID %>_Instance.get_selectedIndex();
},
toString : function()
{
if( <% =this.ClientID %>_Instance )
return <% =this.ClientID %>_Instance.get_selectedIndex();
}
};
<% =this.ClientID %>_DropDownList.setSelectedIndex = function( selectedIndex )
{
if( <% =this.ClientID %>_Instance )
<% =this.ClientID %>_Instance.set_selectedIndex(selectedIndex);
};
}
);
</script>
<div id="<%=this.ClientID %>" style="text-align:left;" >
<asp:Panel ID="header" runat="server">
<asp:TextBox ID="headerText" runat="server" ReadOnly="true" CssClass="SELDropDownListHeaderText" />
<asp:Image ID="arrowImage" runat="server" ImageAlign="AbsMiddle" CssClass="SELDropDownListArrowImage" ImageUrl="~/Images/top_choose_your_location_ArrowButton.gif" />
<div style="clear:both;"></div>
</asp:Panel>
<asp:BulletedList ID="listBox" runat="server" CssClass="SELDropDownListListBox" style="display:none;" />
<asp:HiddenField ID="hdnSelectedIndex" runat="server" Value="-1" />
<asp:LinkButton ID="lbtnDoPostBack" runat="server" Style="display:none;" />
</div>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SELDropDownList.ascx.cs"
Inherits="DropdownlistUserControl.SELDropDownList" %>
<script language="javascript">
var <% =this.ClientID %>_Instance = null;
Sys.Application.add_init(
function(){
<% =this.ClientID %>_Instance = new SELDropDownListBehavior(
{
// Elements
"GlobalContainer" : $get("<%=this.ClientID %>"),
"HeaderContainer" : $get("<% = header.ClientID %>"),
"HeaderText" : $get("<% = headerText.ClientID %>"),
"ArrowImage" : $get("<% = arrowImage.ClientID %>"),
"ListBox" : $get("<% = listBox.ClientID %>"),
"SelectedIndexField" : $get("<% = hdnSelectedIndex.ClientID %>"),
// Properties
"ArrowImageUrl" : "<%=ArrowImageUrl%>",
"ArrowImageHoverUrl" : "<%=ArrowImageHoverUrl %>",
"AutoPostBack" : <%=AutoPostBack.ToString().ToLower() %>,
"SelectedIndexChangeClientScript" : "<%=SelectedIndexChangeClientScript%>",
"DoPostBackElementID" : "<%=lbtnDoPostBack.ClientID%>",
// CSS
"ItemCssClass" : "<%= ItemCssClass %>",
"ItemHoverCssClass" : "<%= ItemHoverCssClass %>",
"ItemAlternateCssClass" : "<%= ItemAlternateCssClass %>",
"ItemAlternateHoverCssClass" : "<%= ItemAlternateHoverCssClass %>",
"ItemSelectedCssClass" : "<%= ItemSelectedCssClass %>",
"ItemSelectedHoverCssClass" : "<%= ItemSelectedHoverCssClass %>"
}
);
// Set the options and selectedIndex
var <% =this.ClientID %>_DropDownList = $get("<% =this.ClientID %>");
<% =this.ClientID %>_DropDownList.options = <%=GetOptionsForClient() %>;
<% =this.ClientID %>_DropDownList.selectedIndex =
{
valueOf : function()
{
if( <% =this.ClientID %>_Instance )
return <% =this.ClientID %>_Instance.get_selectedIndex();
},
toString : function()
{
if( <% =this.ClientID %>_Instance )
return <% =this.ClientID %>_Instance.get_selectedIndex();
}
};
<% =this.ClientID %>_DropDownList.setSelectedIndex = function( selectedIndex )
{
if( <% =this.ClientID %>_Instance )
<% =this.ClientID %>_Instance.set_selectedIndex(selectedIndex);
};
}
);
</script>
<div id="<%=this.ClientID %>" style="text-align:left;" >
<asp:Panel ID="header" runat="server">
<asp:TextBox ID="headerText" runat="server" ReadOnly="true" CssClass="SELDropDownListHeaderText" />
<asp:Image ID="arrowImage" runat="server" ImageAlign="AbsMiddle" CssClass="SELDropDownListArrowImage" ImageUrl="~/Images/top_choose_your_location_ArrowButton.gif" />
<div style="clear:both;"></div>
</asp:Panel>
<asp:BulletedList ID="listBox" runat="server" CssClass="SELDropDownListListBox" style="display:none;" />
<asp:HiddenField ID="hdnSelectedIndex" runat="server" Value="-1" />
<asp:LinkButton ID="lbtnDoPostBack" runat="server" Style="display:none;" />
</div>
2、C#代码部分:
声明了一些属性,并在呈现时做些处理:
Code
//---------------------------------------------------------------------------------------------------------
// Author : 野文(Jasson Qian)
// Date : 2009-5-14
// Description : This is a custom dropdownlist implemented by UserControl in AjaxControlToolkit enviorment
// when developing SonySource project.
// Blogs : http://qguohog.cnblogs.com
// http://blog.csdn.net/sallay
//---------------------------------------------------------------------------------------------------------
// Useage:
// Under Asp.Net/C#:
// 1. It can be used the same as Asp.net DropDownList
// 2. Some CssClass can be reset to change the styles
// 3. We can set some properties to change the UI of the SELDropDownList
// 4. The common.js and style.css should be included in the page that using the SELDropDownList control.
// Client Code:
// 1. We can use it as normal element.
// 2. We can get the element by document.getElementById('<%=UserControlID.ClientID%>'). The properties
// like selectedIndex and options are supported. But we can't set the selected index by selectedIndex
// property directly, the method setSelectedIndex( index ) may instead of it.
//---------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
namespace DropdownlistUserControl
{
public partial class SELDropDownList : System.Web.UI.UserControl
{
#region Properties
private static readonly object SelectedIndexChangedEventKey = new object();
public event EventHandler SelectedIndexChanged
{
add
{
Events.AddHandler(SelectedIndexChangedEventKey, value);
}
remove
{
Events.RemoveHandler(SelectedIndexChangedEventKey, value);
}
}
public ListItemCollection Items
{
get
{
return listBox.Items;
}
}
public int SelectedIndex
{
get
{
return Convert.ToInt32(hdnSelectedIndex.Value);
}
set
{
if (value != SelectedIndex)
{
if (value > -1 && value < Items.Count)
{
hdnSelectedIndex.Value = value.ToString();
headerText.Text = SelectedItem.Text;
}
else
{
hdnSelectedIndex.Value = "-1";
headerText.Text = String.Empty;
}
}
}
}
public ListItem SelectedItem
{
get
{
if (SelectedIndex > -1 && SelectedIndex < Items.Count)
return Items[SelectedIndex];
return null;
}
}
public string SelectedValue
{
get
{
if (SelectedItem != null)
return SelectedItem.Value;
return null;
}
}
public string SelectedText
{
get
{
if (SelectedItem != null)
return SelectedItem.Text;
return null;
}
}
public string ArrowImageUrl
{
get
{
object obj = ViewState["ArrowImageUrl"];
return obj != null ? obj.ToString() : "Images/top_choose_your_location_ArrowButton.gif";
}
set
{
ViewState["ArrowImageUrl"] = value;
arrowImage.ImageUrl = value;
}
}
public string ArrowImageHoverUrl
{
get
{
object obj = ViewState["ArrowImageHoverUrl"];
return obj != null ? obj.ToString() : "Images/top_choose_your_location_ArrowButtonRollover.gif";
}
set
{
ViewState["ArrowImageHoverUrl"] = value;
}
}
public string HeaderTextCssClass
{
get
{
object obj = ViewState["HeaderTextCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["HeaderTextCssClass"] = value;
headerText.CssClass = value;
}
}
public string ArrowImageCssClass
{
get
{
object obj = ViewState["ArrowImageCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["ArrowImageCssClass"] = value;
arrowImage.CssClass = value;
}
}
public string ListBoxCssClass
{
get
{
object obj = ViewState["ListBoxCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["ListBoxCssClass"] = value;
listBox.CssClass = value;
}
}
public string ItemCssClass
{
get
{
object obj = ViewState["ItemCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItem";
}
set
{
ViewState["ItemCssClass"] = value;
}
}
public string ItemHoverCssClass
{
get
{
object obj = ViewState["ItemHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemHover";
}
set
{
ViewState["ItemHoverCssClass"] = value;
}
}
public string ItemAlternateCssClass
{
get
{
object obj = ViewState["ItemAlternateCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemAlternate";
}
set
{
ViewState["ItemAlternateCssClass"] = value;
}
}
public string ItemAlternateHoverCssClass
{
get
{
object obj = ViewState["ItemAlternateHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemAlternateHover";
}
set
{
ViewState["ItemAlternateHoverCssClass"] = value;
}
}
public string ItemSelectedCssClass
{
get
{
object obj = ViewState["ItemSelectedCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemSelected";
}
set
{
ViewState["ItemSelectedCssClass"] = value;
}
}
public string ItemSelectedHoverCssClass
{
get
{
object obj = ViewState["ItemSelectedHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemSelectedHover";
}
set
{
ViewState["ItemSelectedHoverCssClass"] = value;
}
}
/// <summary>
/// Indicate if the control will post back automatically when selected index changed
/// </summary>
public bool AutoPostBack
{
get
{
object obj = ViewState["AutoPostBack"];
return obj != null ? (bool)obj : true;
}
set
{
ViewState["AutoPostBack"] = value;
}
}
/// <summary>
/// Gets or set the width of the header textbox ( not whole header)
/// </summary>
public double ? HeaderTextBoxWidth
{
get
{
object obj = ViewState["HeaderTextBoxWidth"];
return obj != null ? (double ?)obj : null;
}
set
{
ViewState["HeaderTextBoxWidth"] = value;
}
}
/// <summary>
/// Gets or set the max height of the drop down listbox (not include the header textbox).
/// The listbox will show scrollbar if the max height is reached.
/// </summary>
public double? DropDownListBoxMaxHeight
{
get
{
object obj = ViewState["DropDownListBoxMaxHeight"];
return obj != null ? (double?)obj : null;
}
set
{
ViewState["DropDownListBoxMaxHeight"] = value;
}
}
/// <summary>
/// Set the color of the borders
/// The borders include the header textbox and dropdown listbox except arrow image.
/// </summary>
public string BorderCorlor
{
get
{
object obj = ViewState["BorderCorlor"];
return obj != null ? (string)obj : null;
}
set
{
ViewState["BorderCorlor"] = value;
}
}
/// <summary>
/// The client javascript codes that will be invoked when selectedIndex changed.
/// </summary>
public string SelectedIndexChangeClientScript
{
get
{
object obj = ViewState["SelectedIndexChangeClientScript"];
return obj != null ? (string)obj : null;
}
set
{
ViewState["SelectedIndexChangeClientScript"] = value;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
// Raise SelectedIndexChange Event
if (IsPostBack && Request["__EVENTTARGET"] == lbtnDoPostBack.ClientID)
OnSelectedIndexChange();
// Syn header text
headerText.Text = SelectedText;
// Set width of header text box
if (HeaderTextBoxWidth != null)
headerText.Style.Add("width", HeaderTextBoxWidth.ToString()+"px");
// Set border color
if( BorderCorlor!=null )
{
string borderStyle = String.Format("solid 1px {0}",BorderCorlor);
headerText.Style.Add("border-left", borderStyle);
headerText.Style.Add("border-top", borderStyle);
headerText.Style.Add("border-bottom", borderStyle);
listBox.Style.Add("border-left", borderStyle);
listBox.Style.Add("border-right", borderStyle);
listBox.Style.Add("border-bottom", borderStyle);
}
// Set the max-height of listBox
if (DropDownListBoxMaxHeight != null)
listBox.Style.Add("max-height",DropDownListBoxMaxHeight.ToString()+"px");
}
private void OnSelectedIndexChange()
{
EventHandler handler = Events[SelectedIndexChangedEventKey] as EventHandler;
if (handler != null)
handler(this, new EventArgs());
}
protected string GetOptionsForClient()
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
foreach (ListItem li in Items)
{
if (sb.Length > 1)
sb.Append(",");
sb.Append(String.Format("{{\"Text\":\"{0}\",\"Value\":\"{1}\"}}", li.Text, li.Value));
}
sb.Append("]");
return sb.ToString();
}
}
}
//---------------------------------------------------------------------------------------------------------
// Author : 野文(Jasson Qian)
// Date : 2009-5-14
// Description : This is a custom dropdownlist implemented by UserControl in AjaxControlToolkit enviorment
// when developing SonySource project.
// Blogs : http://qguohog.cnblogs.com
// http://blog.csdn.net/sallay
//---------------------------------------------------------------------------------------------------------
// Useage:
// Under Asp.Net/C#:
// 1. It can be used the same as Asp.net DropDownList
// 2. Some CssClass can be reset to change the styles
// 3. We can set some properties to change the UI of the SELDropDownList
// 4. The common.js and style.css should be included in the page that using the SELDropDownList control.
// Client Code:
// 1. We can use it as normal element.
// 2. We can get the element by document.getElementById('<%=UserControlID.ClientID%>'). The properties
// like selectedIndex and options are supported. But we can't set the selected index by selectedIndex
// property directly, the method setSelectedIndex( index ) may instead of it.
//---------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
namespace DropdownlistUserControl
{
public partial class SELDropDownList : System.Web.UI.UserControl
{
#region Properties
private static readonly object SelectedIndexChangedEventKey = new object();
public event EventHandler SelectedIndexChanged
{
add
{
Events.AddHandler(SelectedIndexChangedEventKey, value);
}
remove
{
Events.RemoveHandler(SelectedIndexChangedEventKey, value);
}
}
public ListItemCollection Items
{
get
{
return listBox.Items;
}
}
public int SelectedIndex
{
get
{
return Convert.ToInt32(hdnSelectedIndex.Value);
}
set
{
if (value != SelectedIndex)
{
if (value > -1 && value < Items.Count)
{
hdnSelectedIndex.Value = value.ToString();
headerText.Text = SelectedItem.Text;
}
else
{
hdnSelectedIndex.Value = "-1";
headerText.Text = String.Empty;
}
}
}
}
public ListItem SelectedItem
{
get
{
if (SelectedIndex > -1 && SelectedIndex < Items.Count)
return Items[SelectedIndex];
return null;
}
}
public string SelectedValue
{
get
{
if (SelectedItem != null)
return SelectedItem.Value;
return null;
}
}
public string SelectedText
{
get
{
if (SelectedItem != null)
return SelectedItem.Text;
return null;
}
}
public string ArrowImageUrl
{
get
{
object obj = ViewState["ArrowImageUrl"];
return obj != null ? obj.ToString() : "Images/top_choose_your_location_ArrowButton.gif";
}
set
{
ViewState["ArrowImageUrl"] = value;
arrowImage.ImageUrl = value;
}
}
public string ArrowImageHoverUrl
{
get
{
object obj = ViewState["ArrowImageHoverUrl"];
return obj != null ? obj.ToString() : "Images/top_choose_your_location_ArrowButtonRollover.gif";
}
set
{
ViewState["ArrowImageHoverUrl"] = value;
}
}
public string HeaderTextCssClass
{
get
{
object obj = ViewState["HeaderTextCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["HeaderTextCssClass"] = value;
headerText.CssClass = value;
}
}
public string ArrowImageCssClass
{
get
{
object obj = ViewState["ArrowImageCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["ArrowImageCssClass"] = value;
arrowImage.CssClass = value;
}
}
public string ListBoxCssClass
{
get
{
object obj = ViewState["ListBoxCssClass"];
return obj != null ? obj.ToString() : null;
}
set
{
ViewState["ListBoxCssClass"] = value;
listBox.CssClass = value;
}
}
public string ItemCssClass
{
get
{
object obj = ViewState["ItemCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItem";
}
set
{
ViewState["ItemCssClass"] = value;
}
}
public string ItemHoverCssClass
{
get
{
object obj = ViewState["ItemHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemHover";
}
set
{
ViewState["ItemHoverCssClass"] = value;
}
}
public string ItemAlternateCssClass
{
get
{
object obj = ViewState["ItemAlternateCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemAlternate";
}
set
{
ViewState["ItemAlternateCssClass"] = value;
}
}
public string ItemAlternateHoverCssClass
{
get
{
object obj = ViewState["ItemAlternateHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemAlternateHover";
}
set
{
ViewState["ItemAlternateHoverCssClass"] = value;
}
}
public string ItemSelectedCssClass
{
get
{
object obj = ViewState["ItemSelectedCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemSelected";
}
set
{
ViewState["ItemSelectedCssClass"] = value;
}
}
public string ItemSelectedHoverCssClass
{
get
{
object obj = ViewState["ItemSelectedHoverCssClass"];
return obj != null ? obj.ToString() : "SELDropDownListListItemSelectedHover";
}
set
{
ViewState["ItemSelectedHoverCssClass"] = value;
}
}
/// <summary>
/// Indicate if the control will post back automatically when selected index changed
/// </summary>
public bool AutoPostBack
{
get
{
object obj = ViewState["AutoPostBack"];
return obj != null ? (bool)obj : true;
}
set
{
ViewState["AutoPostBack"] = value;
}
}
/// <summary>
/// Gets or set the width of the header textbox ( not whole header)
/// </summary>
public double ? HeaderTextBoxWidth
{
get
{
object obj = ViewState["HeaderTextBoxWidth"];
return obj != null ? (double ?)obj : null;
}
set
{
ViewState["HeaderTextBoxWidth"] = value;
}
}
/// <summary>
/// Gets or set the max height of the drop down listbox (not include the header textbox).
/// The listbox will show scrollbar if the max height is reached.
/// </summary>
public double? DropDownListBoxMaxHeight
{
get
{
object obj = ViewState["DropDownListBoxMaxHeight"];
return obj != null ? (double?)obj : null;
}
set
{
ViewState["DropDownListBoxMaxHeight"] = value;
}
}
/// <summary>
/// Set the color of the borders
/// The borders include the header textbox and dropdown listbox except arrow image.
/// </summary>
public string BorderCorlor
{
get
{
object obj = ViewState["BorderCorlor"];
return obj != null ? (string)obj : null;
}
set
{
ViewState["BorderCorlor"] = value;
}
}
/// <summary>
/// The client javascript codes that will be invoked when selectedIndex changed.
/// </summary>
public string SelectedIndexChangeClientScript
{
get
{
object obj = ViewState["SelectedIndexChangeClientScript"];
return obj != null ? (string)obj : null;
}
set
{
ViewState["SelectedIndexChangeClientScript"] = value;
}
}
#endregion
protected void Page_Load(object sender, EventArgs e)
{
// Raise SelectedIndexChange Event
if (IsPostBack && Request["__EVENTTARGET"] == lbtnDoPostBack.ClientID)
OnSelectedIndexChange();
// Syn header text
headerText.Text = SelectedText;
// Set width of header text box
if (HeaderTextBoxWidth != null)
headerText.Style.Add("width", HeaderTextBoxWidth.ToString()+"px");
// Set border color
if( BorderCorlor!=null )
{
string borderStyle = String.Format("solid 1px {0}",BorderCorlor);
headerText.Style.Add("border-left", borderStyle);
headerText.Style.Add("border-top", borderStyle);
headerText.Style.Add("border-bottom", borderStyle);
listBox.Style.Add("border-left", borderStyle);
listBox.Style.Add("border-right", borderStyle);
listBox.Style.Add("border-bottom", borderStyle);
}
// Set the max-height of listBox
if (DropDownListBoxMaxHeight != null)
listBox.Style.Add("max-height",DropDownListBoxMaxHeight.ToString()+"px");
}
private void OnSelectedIndexChange()
{
EventHandler handler = Events[SelectedIndexChangedEventKey] as EventHandler;
if (handler != null)
handler(this, new EventArgs());
}
protected string GetOptionsForClient()
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
foreach (ListItem li in Items)
{
if (sb.Length > 1)
sb.Append(",");
sb.Append(String.Format("{{\"Text\":\"{0}\",\"Value\":\"{1}\"}}", li.Text, li.Value));
}
sb.Append("]");
return sb.ToString();
}
}
}
3、用Javascript实现的SELDropDownListBehavior部分:
javascript主要用来控制各个控件的展现和状态:
Code
function SELDropDownListBehavior(elements) {
// Elements
this._globalContainer = null;
this._headerContainer = null;
this._headerText = null;
this._arrowImage = null;
this._listBox = null;
this._selectedIndexField = null;
// Properties
this._arrowImageUrl = null;
this._arrowImageHoverUrl = null;
this._autoPostBack = true;
this._selectedIndexChangeClientScript = null;
this._doPostBackElementID = null;
// CSS
this._itemCssClass = null;
this._itemHoverCssClass = null;
this._itemAlternateCssClass = null;
this._itemAlternateHoverCssClass = null;
this._itemSelectedCssClass = null;
this._itemSelectedHoverCssClass = null;
// Inits
this.initialize(elements);
this.measureSize();
this.regEvents();
}
SELDropDownListBehavior.prototype = {
initialize: function(elements) {
// Elements
if (this.isValid(elements.GlobalContainer))
this._globalContainer = elements.GlobalContainer;
if (this.isValid(elements.HeaderContainer))
this._headerContainer = elements.HeaderContainer;
if (this.isValid(elements.HeaderText))
this._headerText = elements.HeaderText;
if (this.isValid(elements.ArrowImage))
this._arrowImage = elements.ArrowImage;
if (this.isValid(elements.ListBox))
this._listBox = elements.ListBox;
if (this.isValid(elements.SelectedIndexField))
this._selectedIndexField = elements.SelectedIndexField;
// Properties
if (this.isValid(elements.ArrowImageUrl))
this._arrowImageUrl = elements.ArrowImageUrl;
if (this.isValid(elements.ArrowImageHoverUrl))
this._arrowImageHoverUrl = elements.ArrowImageHoverUrl;
if (this.isValid(elements.AutoPostBack))
this._autoPostBack = elements.AutoPostBack;
if (this.isValid(elements.SelectedIndexChangeClientScript))
this._selectedIndexChangeClientScript = elements.SelectedIndexChangeClientScript;
if (this.isValid(elements.DoPostBackElementID))
this._doPostBackElementID = elements.DoPostBackElementID;
// CSS
if (this.isValid(elements.ItemCssClass))
this._itemCssClass = elements.ItemCssClass;
if (this.isValid(elements.ItemHoverCssClass))
this._itemHoverCssClass = elements.ItemHoverCssClass;
if (this.isValid(elements.ItemAlternateCssClass))
this._itemAlternateCssClass = elements.ItemAlternateCssClass;
if (this.isValid(elements.ItemAlternateHoverCssClass))
this._itemAlternateHoverCssClass = elements.ItemAlternateHoverCssClass;
if (this.isValid(elements.ItemSelectedCssClass))
this._itemSelectedCssClass = elements.ItemSelectedCssClass;
if (this.isValid(elements.ItemSelectedHoverCssClass))
this._itemSelectedHoverCssClass = elements.ItemSelectedHoverCssClass;
},
measureSize: function() {
var storeObjs = [];
// save elements which will be setted to display='block' from display='none'
var curObj = this._globalContainer;
while (curObj != null) {
if (curObj.style != null && curObj.style.display == "none") {
storeObjs[storeObjs.length++] = { "obj": curObj, "display": curObj.style.display, "visibility": curObj.style.visibility };
curObj.style.visibility = "hidden";
curObj.style.display = "";
}
curObj = curObj.parentNode;
}
var headerWidth = this._headerText.offsetWidth + this._arrowImage.offsetWidth;
var headerHeight = Math.max(this._headerText.offsetHeight, this._arrowImage.offsetHeight);
if (this._listBox != null && headerWidth > 0)
this._listBox.style.width = (headerWidth - 2) + "px";
if (this._globalContainer != null && headerWidth > 0) {
this._globalContainer.style.width = headerWidth + "px";
this._globalContainer.style.height = headerHeight + "px";
}
// restore the style.display and style.visibility
for (var i = 0; i < storeObjs.length; i++) {
storeObjs[i].obj.style.display = storeObjs[i].display;
storeObjs[i].obj.style.visibility = storeObjs[i].visibility;
}
},
regEvents: function() {
// reg events of listItems
var listItems = this.get_listItems();
for (var i = 0; i < listItems.length; i++) {
var item = listItems[i];
$addHandler(item, "mouseover", this.getItemMouseOverHandler(item));
$addHandler(item, "click", this.getItemClickHandler(item));
}
// reg events of header clicking
$addHandler(this._headerText, "click", SELDropDownListBehavior.createDelegate(this, this.headerClickHandler));
$addHandler(this._arrowImage, "click", SELDropDownListBehavior.createDelegate(this, this.headerClickHandler));
// reg events of arrowImage
$addHandler(this._arrowImage, "mouseover", SELDropDownListBehavior.createDelegate(this, this.arrowImageMouseOverHandler));
$addHandler(this._arrowImage, "mouseout", SELDropDownListBehavior.createDelegate(this, this.arrowImageMouseOutHandler));
// reg events of document.click
$addHandler(document, "click", SELDropDownListBehavior.createDelegate(this, this.documentClickHandler));
},
set_selectedIndex: function(selectedIndex) {
if (this._selectedIndexField != null)
this._selectedIndexField.value = selectedIndex;
this._headerText.value = this.get_selectedText();
if (this.isListBoxPopup())
this.showListBox();
},
get_listItems: function() {
if (this.isValid(this._listBox))
return this._listBox.getElementsByTagName("li");
return [];
},
get_selectedIndex: function() {
if (this._selectedIndexField)
return this._selectedIndexField.value;
return -1;
},
get_listItemIndex: function(listItem) {
var listItems = this.get_listItems();
for (var i = 0; i < listItems.length; i++) {
if (listItem == listItems[i])
return i;
}
return -1;
},
get_selectedListItem: function() {
var selectedIndex = this.get_selectedIndex();
var listItems = this.get_listItems();
if (selectedIndex > -1 && selectedIndex < listItems.length)
return listItems[selectedIndex];
return null;
},
get_selectedText: function() {
var selectedItem = this.get_selectedListItem();
if (selectedItem)
return selectedItem.innerHTML;
return "";
},
isValid: function(el) {
return (el != null && typeof (el) != 'undefined' && el.toString() != "");
},
hideListBox: function() {
if (this._listBox != null)
this._listBox.style.display = "none";
},
showListBox: function() {
if (this._listBox != null)
this._listBox.style.display = "block";
this.resetAllListItemsCssClass();
// Set selectedItem to MouseOver Class if no ItemSelectedCssClass was setted
var selectedListItem = this.get_selectedListItem();
if (selectedListItem && !this._itemSelectedCssClass) {
if (this.get_selectedIndex() % 2 == 1 && this._itemAlternateHoverCssClass)
selectedListItem.className = this._itemAlternateHoverCssClass;
else
selectedListItem.className = this._itemAlternateCssClass;
}
},
isListBoxPopup: function() {
if (this._listBox != null)
return this._listBox.style.display != "none";
return false;
},
resetAllListItemsCssClass: function() {
// set class of all item/alternate items
var listItems = this.get_listItems();
var selectedIndex = this.get_selectedIndex();
for (var i = 0; i < listItems.length; i++) {
var listItem = listItems[i];
if (i == selectedIndex && this._itemSelectedCssClass)
listItem.className = this._itemSelectedCssClass;
else {
if (i % 2 == 1 && this.isValid(this._itemAlternateCssClass))
listItem.className = this._itemAlternateCssClass;
else
listItem.className = this._itemCssClass;
}
}
},
setListItemMouseOver: function(listItem) {
this.resetAllListItemsCssClass();
var index = this.get_listItemIndex(listItem);
if (index == this.get_selectedIndex() && this._itemSelectedHoverCssClass != null)
listItem.className = this._itemSelectedHoverCssClass;
else {
if (index % 2 == 1 && this.isValid(this._itemAlternateHoverCssClass))
listItem.className = this._itemAlternateHoverCssClass;
else
listItem.className = this._itemHoverCssClass;
}
},
postBack: function() {
if (__doPostBack)
__doPostBack(this._doPostBackElementID, "");
},
selecteListItem: function(listItem) {
var selectedIndex = this.get_listItemIndex(listItem);
if (this.get_selectedIndex() != selectedIndex) {
this._selectedIndexField.value = selectedIndex;
this.resetAllListItemsCssClass();
if (this._itemSelectedHoverCssClass)
listItem.className = this._itemSelectedHoverCssClass;
this._headerText.value = listItem.innerHTML;
if (this.isValid(this._selectedIndexChangeClientScript))
eval(this._selectedIndexChangeClientScript);
if (this._autoPostBack)
this.postBack();
else
this.hideListBox();
}
else
this.hideListBox();
},
getItemMouseOverHandler: function(listItem) {
var ddl = this;
return function() {
ddl.setListItemMouseOver(listItem);
}
},
getItemClickHandler: function(listItem) {
var ddl = this;
return function() {
ddl.selecteListItem(listItem);
}
},
headerClickHandler: function(e) {
if (this.isListBoxPopup())
this.hideListBox();
else
this.showListBox();
},
arrowImageMouseOverHandler: function() {
this._arrowImage.src = this._arrowImageHoverUrl;
},
arrowImageMouseOutHandler: function() {
this._arrowImage.src = this._arrowImageUrl;
},
documentClickHandler: function(e) {
e = window.event || e;
var srcE = e.srcElement || e.target;
while (srcE != null) {
if (srcE == this._headerContainer || srcE == this._listBox)
return;
else
srcE = srcE.parentNode;
}
if (this.isListBoxPopup())
this.hideListBox();
}
}
SELDropDownListBehavior.createDelegate = function(instance, method) {
return function() {
return method.apply(instance, arguments);
}
}
function SELDropDownListBehavior(elements) {
// Elements
this._globalContainer = null;
this._headerContainer = null;
this._headerText = null;
this._arrowImage = null;
this._listBox = null;
this._selectedIndexField = null;
// Properties
this._arrowImageUrl = null;
this._arrowImageHoverUrl = null;
this._autoPostBack = true;
this._selectedIndexChangeClientScript = null;
this._doPostBackElementID = null;
// CSS
this._itemCssClass = null;
this._itemHoverCssClass = null;
this._itemAlternateCssClass = null;
this._itemAlternateHoverCssClass = null;
this._itemSelectedCssClass = null;
this._itemSelectedHoverCssClass = null;
// Inits
this.initialize(elements);
this.measureSize();
this.regEvents();
}
SELDropDownListBehavior.prototype = {
initialize: function(elements) {
// Elements
if (this.isValid(elements.GlobalContainer))
this._globalContainer = elements.GlobalContainer;
if (this.isValid(elements.HeaderContainer))
this._headerContainer = elements.HeaderContainer;
if (this.isValid(elements.HeaderText))
this._headerText = elements.HeaderText;
if (this.isValid(elements.ArrowImage))
this._arrowImage = elements.ArrowImage;
if (this.isValid(elements.ListBox))
this._listBox = elements.ListBox;
if (this.isValid(elements.SelectedIndexField))
this._selectedIndexField = elements.SelectedIndexField;
// Properties
if (this.isValid(elements.ArrowImageUrl))
this._arrowImageUrl = elements.ArrowImageUrl;
if (this.isValid(elements.ArrowImageHoverUrl))
this._arrowImageHoverUrl = elements.ArrowImageHoverUrl;
if (this.isValid(elements.AutoPostBack))
this._autoPostBack = elements.AutoPostBack;
if (this.isValid(elements.SelectedIndexChangeClientScript))
this._selectedIndexChangeClientScript = elements.SelectedIndexChangeClientScript;
if (this.isValid(elements.DoPostBackElementID))
this._doPostBackElementID = elements.DoPostBackElementID;
// CSS
if (this.isValid(elements.ItemCssClass))
this._itemCssClass = elements.ItemCssClass;
if (this.isValid(elements.ItemHoverCssClass))
this._itemHoverCssClass = elements.ItemHoverCssClass;
if (this.isValid(elements.ItemAlternateCssClass))
this._itemAlternateCssClass = elements.ItemAlternateCssClass;
if (this.isValid(elements.ItemAlternateHoverCssClass))
this._itemAlternateHoverCssClass = elements.ItemAlternateHoverCssClass;
if (this.isValid(elements.ItemSelectedCssClass))
this._itemSelectedCssClass = elements.ItemSelectedCssClass;
if (this.isValid(elements.ItemSelectedHoverCssClass))
this._itemSelectedHoverCssClass = elements.ItemSelectedHoverCssClass;
},
measureSize: function() {
var storeObjs = [];
// save elements which will be setted to display='block' from display='none'
var curObj = this._globalContainer;
while (curObj != null) {
if (curObj.style != null && curObj.style.display == "none") {
storeObjs[storeObjs.length++] = { "obj": curObj, "display": curObj.style.display, "visibility": curObj.style.visibility };
curObj.style.visibility = "hidden";
curObj.style.display = "";
}
curObj = curObj.parentNode;
}
var headerWidth = this._headerText.offsetWidth + this._arrowImage.offsetWidth;
var headerHeight = Math.max(this._headerText.offsetHeight, this._arrowImage.offsetHeight);
if (this._listBox != null && headerWidth > 0)
this._listBox.style.width = (headerWidth - 2) + "px";
if (this._globalContainer != null && headerWidth > 0) {
this._globalContainer.style.width = headerWidth + "px";
this._globalContainer.style.height = headerHeight + "px";
}
// restore the style.display and style.visibility
for (var i = 0; i < storeObjs.length; i++) {
storeObjs[i].obj.style.display = storeObjs[i].display;
storeObjs[i].obj.style.visibility = storeObjs[i].visibility;
}
},
regEvents: function() {
// reg events of listItems
var listItems = this.get_listItems();
for (var i = 0; i < listItems.length; i++) {
var item = listItems[i];
$addHandler(item, "mouseover", this.getItemMouseOverHandler(item));
$addHandler(item, "click", this.getItemClickHandler(item));
}
// reg events of header clicking
$addHandler(this._headerText, "click", SELDropDownListBehavior.createDelegate(this, this.headerClickHandler));
$addHandler(this._arrowImage, "click", SELDropDownListBehavior.createDelegate(this, this.headerClickHandler));
// reg events of arrowImage
$addHandler(this._arrowImage, "mouseover", SELDropDownListBehavior.createDelegate(this, this.arrowImageMouseOverHandler));
$addHandler(this._arrowImage, "mouseout", SELDropDownListBehavior.createDelegate(this, this.arrowImageMouseOutHandler));
// reg events of document.click
$addHandler(document, "click", SELDropDownListBehavior.createDelegate(this, this.documentClickHandler));
},
set_selectedIndex: function(selectedIndex) {
if (this._selectedIndexField != null)
this._selectedIndexField.value = selectedIndex;
this._headerText.value = this.get_selectedText();
if (this.isListBoxPopup())
this.showListBox();
},
get_listItems: function() {
if (this.isValid(this._listBox))
return this._listBox.getElementsByTagName("li");
return [];
},
get_selectedIndex: function() {
if (this._selectedIndexField)
return this._selectedIndexField.value;
return -1;
},
get_listItemIndex: function(listItem) {
var listItems = this.get_listItems();
for (var i = 0; i < listItems.length; i++) {
if (listItem == listItems[i])
return i;
}
return -1;
},
get_selectedListItem: function() {
var selectedIndex = this.get_selectedIndex();
var listItems = this.get_listItems();
if (selectedIndex > -1 && selectedIndex < listItems.length)
return listItems[selectedIndex];
return null;
},
get_selectedText: function() {
var selectedItem = this.get_selectedListItem();
if (selectedItem)
return selectedItem.innerHTML;
return "";
},
isValid: function(el) {
return (el != null && typeof (el) != 'undefined' && el.toString() != "");
},
hideListBox: function() {
if (this._listBox != null)
this._listBox.style.display = "none";
},
showListBox: function() {
if (this._listBox != null)
this._listBox.style.display = "block";
this.resetAllListItemsCssClass();
// Set selectedItem to MouseOver Class if no ItemSelectedCssClass was setted
var selectedListItem = this.get_selectedListItem();
if (selectedListItem && !this._itemSelectedCssClass) {
if (this.get_selectedIndex() % 2 == 1 && this._itemAlternateHoverCssClass)
selectedListItem.className = this._itemAlternateHoverCssClass;
else
selectedListItem.className = this._itemAlternateCssClass;
}
},
isListBoxPopup: function() {
if (this._listBox != null)
return this._listBox.style.display != "none";
return false;
},
resetAllListItemsCssClass: function() {
// set class of all item/alternate items
var listItems = this.get_listItems();
var selectedIndex = this.get_selectedIndex();
for (var i = 0; i < listItems.length; i++) {
var listItem = listItems[i];
if (i == selectedIndex && this._itemSelectedCssClass)
listItem.className = this._itemSelectedCssClass;
else {
if (i % 2 == 1 && this.isValid(this._itemAlternateCssClass))
listItem.className = this._itemAlternateCssClass;
else
listItem.className = this._itemCssClass;
}
}
},
setListItemMouseOver: function(listItem) {
this.resetAllListItemsCssClass();
var index = this.get_listItemIndex(listItem);
if (index == this.get_selectedIndex() && this._itemSelectedHoverCssClass != null)
listItem.className = this._itemSelectedHoverCssClass;
else {
if (index % 2 == 1 && this.isValid(this._itemAlternateHoverCssClass))
listItem.className = this._itemAlternateHoverCssClass;
else
listItem.className = this._itemHoverCssClass;
}
},
postBack: function() {
if (__doPostBack)
__doPostBack(this._doPostBackElementID, "");
},
selecteListItem: function(listItem) {
var selectedIndex = this.get_listItemIndex(listItem);
if (this.get_selectedIndex() != selectedIndex) {
this._selectedIndexField.value = selectedIndex;
this.resetAllListItemsCssClass();
if (this._itemSelectedHoverCssClass)
listItem.className = this._itemSelectedHoverCssClass;
this._headerText.value = listItem.innerHTML;
if (this.isValid(this._selectedIndexChangeClientScript))
eval(this._selectedIndexChangeClientScript);
if (this._autoPostBack)
this.postBack();
else
this.hideListBox();
}
else
this.hideListBox();
},
getItemMouseOverHandler: function(listItem) {
var ddl = this;
return function() {
ddl.setListItemMouseOver(listItem);
}
},
getItemClickHandler: function(listItem) {
var ddl = this;
return function() {
ddl.selecteListItem(listItem);
}
},
headerClickHandler: function(e) {
if (this.isListBoxPopup())
this.hideListBox();
else
this.showListBox();
},
arrowImageMouseOverHandler: function() {
this._arrowImage.src = this._arrowImageHoverUrl;
},
arrowImageMouseOutHandler: function() {
this._arrowImage.src = this._arrowImageUrl;
},
documentClickHandler: function(e) {
e = window.event || e;
var srcE = e.srcElement || e.target;
while (srcE != null) {
if (srcE == this._headerContainer || srcE == this._listBox)
return;
else
srcE = srcE.parentNode;
}
if (this.isListBoxPopup())
this.hideListBox();
}
}
SELDropDownListBehavior.createDelegate = function(instance, method) {
return function() {
return method.apply(instance, arguments);
}
}
4、调用SELDropDownList
调用SELDropDownList首先要求在AjaxControlToolKit环境下,其次要引用对应的js文件来包含SELDropDownListBehavior:
Code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DropdownlistUserControl._Default" %>
<%@ Register Assembly="AjaxControlToolkit, Version=3.0.20820.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"
Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<%@ Register Src="SELDropDownList.ascx" TagName="SELDropDownList" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" href="Style.css" type="text/css" />
</head>
<body style="background: black">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="MyScriptManager" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Common.js" />
</Scripts>
</asp:ScriptManager>
<uc1:SELDropDownList ID="SELDropDownList1" runat="server" AutoPostBack="true" />
<br />
<div id="secContainer" style="display:none">
<div>
<uc1:SELDropDownList ID="SELDropDownList2" runat="server" AutoPostBack="true" SelectedIndexChangeClientScript="t()"
DropDownListBoxMaxHeight="100" />
</div>
</div>
<input type="button" value="Show Sencond" onclick="document.getElementById('secContainer').style.display='block'" />
</div>
</form>
</body>
</html>
<script>
function t() {
var a = document.getElementById("<%=SELDropDownList1.ClientID%>");
a.setSelectedIndex(3);
}
</script>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DropdownlistUserControl._Default" %>
<%@ Register Assembly="AjaxControlToolkit, Version=3.0.20820.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e"
Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<%@ Register Src="SELDropDownList.ascx" TagName="SELDropDownList" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" href="Style.css" type="text/css" />
</head>
<body style="background: black">
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="MyScriptManager" runat="server">
<Scripts>
<asp:ScriptReference Path="~/Common.js" />
</Scripts>
</asp:ScriptManager>
<uc1:SELDropDownList ID="SELDropDownList1" runat="server" AutoPostBack="true" />
<br />
<div id="secContainer" style="display:none">
<div>
<uc1:SELDropDownList ID="SELDropDownList2" runat="server" AutoPostBack="true" SelectedIndexChangeClientScript="t()"
DropDownListBoxMaxHeight="100" />
</div>
</div>
<input type="button" value="Show Sencond" onclick="document.getElementById('secContainer').style.display='block'" />
</div>
</form>
</body>
</html>
<script>
function t() {
var a = document.getElementById("<%=SELDropDownList1.ClientID%>");
a.setSelectedIndex(3);
}
</script>
当然,这个控件还有很多需要完善和扩展的地方,例如滚动条的样式,背景色等等。通过修改对应的Class可以改变大部分样式,但一般没有必要修改CSS。对应的代码可以在这里下载。
=======================================================================
野文(Jasson Qian)
------------------------------------------------------
博客园:http://qguohog.cnblogs.com
CSDN:http://blog.csdn.net/sallay