[Asp.Net]ListBox联动控件
最近学习Asp.net Ajax控件开发,自己写了一个 CascadingListBox 控件对应于 AjaxControlToolkit 中的 CascadingDropDown,基本功能都实现了,代码如下:
1
using System;2
using System.Collections.Generic;3
using System.ComponentModel;4
using System.Web.UI;5
using System.Web.UI.WebControls;6

7
namespace yixin_webcontrols8


{9

/**//// <summary>10
/// 联动ListBox11
/// </summary>12
[DefaultProperty("TargetControlID")]13
[ToolboxData("<{0}:CascadingListBox runat=server Category=\"\" LoadingText=\"\" EmptyText=\"\" TargetControlID=\"\" ParentControlID=\"\" ServiceMethod=\"\" ServicePath=\"\" />")]14
[TargetControlType(typeof(ListBox))]15
public class CascadingListBox : ExtenderControl16

{17
private string _ParentControlID;18

/**//// <summary>19
/// 父ListBox控件20
/// </summary>21
[IDReferenceProperty(typeof(ListBox))]22
[DefaultValue("")]23
[Category("绑定控件")]24
[Description("设置父ListBox控件")]25
public string ParentControlID26

{27
get 28

{29
return _ParentControlID;30
}31
set32

{33
_ParentControlID = value;34
}35
}36

37
private string _Category;38

/**//// <summary>39
/// 设置分类/种类,用于区分绑定的ListBox显示的类别40
/// </summary>41
[DefaultValue("")]42
[Category("必选属性")]43
[Description("设置分类/种类,用于区分绑定的ListBox显示的类别")]44
public string Category45

{46

get
{ return _Category; }47

set
{ _Category = value; }48
}49

50
private string _EmptyText;51

/**//// <summary>52
/// 当没有父分类没有选中任何数据时ListBox显示的文本 如:请选择父分类53
/// </summary>54
[DefaultValue("")]55
[Category("可选属性")]56
[Description("当没有父分类没有选中任何数据时ListBox显示的文本 如:请选择父分类")]57

public string EmptyText
{ get
{ return _EmptyText; } set
{ _EmptyText = value; } }58

59
private string _LoadingText;60

/**//// <summary>61
/// 当ListBox正在请求服务器数据时显示的文本 如:正在加载
62
/// 不设置此属性将默认显示“正在加载
”63
/// </summary>64
[DefaultValue("")]65
[Category("可选属性")]66
[Description("当ListBox正在请求服务器数据时显示的文本 如:正在加载
,不设置此属性将默认显示“正在加载
”")]67

public string LoadingText
{ get
{ return _LoadingText; } set
{ _LoadingText = value; } }68

69
private string _ServicePath;70

/**//// <summary>71
/// 设置ListBox请求数据的web服务路径72
/// </summary>73
[UrlProperty()]74
[DefaultValue("")]75
[Category("必选属性")]76
[Description("设置ListBox请求数据的web服务路径")]77

public string ServicePath
{ get
{ return _ServicePath; } set
{ _ServicePath = value; } }78

79
private string _ServiceMethod;80

/**//// <summary>81
/// 设置ListBox请求数据的web服务中调用的方法82
/// </summary>83
[DefaultValue("")]84
[Category("必选属性")]85
[Description("设置ListBox请求数据的web服务中调用的方法")]86

public string ServiceMethod
{ get
{ return _ServiceMethod; } set
{ _ServiceMethod = value; } }87

88

/**//// <summary>89
/// 重写基类GetScriptDescriptors()方法 添加控件客户端属性90
/// </summary>91
/// <param name="targetControl"></param>92
/// <returns></returns>93
protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)94

{95
ScriptBehaviorDescriptor descriptor = new ScriptBehaviorDescriptor("Yinxin_WebControls.CascadingListBoxBehavior", targetControl.ClientID);96
if(_ParentControlID!=null)97
descriptor.AddProperty("ParentControlID", this._ParentControlID);98
descriptor.AddProperty("Category", this._Category);99
if(_EmptyText!=null)100
descriptor.AddProperty("EmptyText", this._EmptyText);101
if(_LoadingText !=null)102
descriptor.AddProperty("LoadingText", this._LoadingText);103
descriptor.AddProperty("ServicePath", this._ServicePath);104
descriptor.AddProperty("ServiceMethod", this._ServiceMethod);105

return new ScriptDescriptor[]
{ descriptor };106
}107

/**//// <summary>108
/// 重写基类GetScriptReferences()方法 注册yixin_webcontrols.CascadingListBoxBehavior客户端类型109
/// </summary>110
/// <returns></returns>111
protected override IEnumerable<ScriptReference> GetScriptReferences()112

{113

return new ScriptReference[]
{ new ScriptReference(Page.ClientScript.GetWebResourceUrl(this.GetType(),"yixin_webcontrols.CascadingListBoxBehavior.js")) };114
}115
}116
}117

1
using System;2

3
namespace yixin_webcontrols4


{5

/**//// <summary>6
/// 用于Web服务返回的ListBox键值对7
/// </summary>8
[Serializable]9
public class CascadingListBoxNameValue10

{11

/**//// <summary>12
/// ListBox.Option显示的文本13
/// </summary>14
public string Name;15

/**//// <summary>16
/// ListBox.Option的值17
/// </summary>18
public string Value;19

/**//// <summary>20
/// ListBox.Option是否被选中21
/// </summary>22
public bool isDefaultValue;23

24

/**//// <summary>25
/// 初始化一个空白的CascadingListBoxNameValue对象26
/// </summary>27
public CascadingListBoxNameValue()28

{29
}30

/**//// <summary>31
/// 初始化一个CascadingListBoxNameValue对象32
/// </summary>33
/// <param name="name">ListBox.Option显示的文本</param>34
/// <param name="value">ListBox.Option的值</param>35
public CascadingListBoxNameValue(string name, string value)36

{37
this.Name = name;38
this.Value = value;39
}40

/**//// <summary>41
/// 初始化一个CascadingListBoxNameValue对象42
/// </summary>43
/// <param name="name">ListBox.Option显示的文本</param>44
/// <param name="value">ListBox.Option的值</param>45
/// <param name="defaultValue">ListBox.Option是否被选中</param>46
public CascadingListBoxNameValue(string name, string value, bool defaultValue)47

{48
this.Name = name;49
this.Value = value;50
this.isDefaultValue = defaultValue;51
}52
}53
}54

1
/// <reference name="MicrosoftAjax.js"/>2

3
Type.registerNamespace("Yinxin_WebControls");4

5

Yinxin_WebControls.CascadingListBoxBehavior = function(element)
{6
Yinxin_WebControls.CascadingListBoxBehavior.initializeBase(this, [element]);7
this._ParentControlID = null;8
this._Category = null;9
this._EmptyText = "[没有数据]";10
this._LoadingText = "[正在加载
]";11
this._ServicePath = null;12
this._ServiceMethod = null;13
}14

Yinxin_WebControls.CascadingListBoxBehavior.prototype =
{15
//属性16

get_ParentControlID: function()
{17
return this._ParentControlID;18
},19

set_ParentControlID: function(value)
{20
this._ParentControlID = value;21
},22

get_Category: function()
{23
return this._Category;24
},25

set_Category: function(value)
{26
this._Category = value;27
},28

get_EmptyText: function()
{29
return this._EmptyText;30
},31

set_EmptyText: function(value)
{32
this._EmptyText = value;33
},34

get_LoadingText: function()
{35
return this._LoadingText;36
},37

set_LoadingText: function(value)
{38
this._LoadingText = value;39
},40

get_ServicePath: function()
{41
return this._ServicePath;42
},43

set_ServicePath: function(value)
{44
this._ServicePath = value;45
},46

get_ServiceMethod: function()
{47
return this._ServiceMethod;48
},49

set_ServiceMethod: function(value)
{50
this._ServiceMethod = value;51
},52
//方法53

Disable: function()
{54
this.get_element().disabled = 'disabled';55
},56

Enable: function()
{57
this.get_element().disabled = '';58
},59

ClearItems: function()
{60
this.get_element().innerHTML = "";61
},62

AddOption: function(Name, Value, isSelected)
{63
var optionElement = new Option(Name, Value);64
if (isSelected)65
optionElement.selected = true;66
this.get_element().options[this.get_element().options.length] = optionElement;67
},68
//事件处理69

_onParentChange: function(e, ParentisNull)
{70
var knownCategoryValues = "";71

if (!ParentisNull)
{72
knownCategoryValues = this._ParentElement.value;73
if (knownCategoryValues == "")74
return false;75
}76
this.ClearItems();77
this.AddOption(this._LoadingText, "");78

var params =
{ "knownCategoryValues": knownCategoryValues, "category": this._Category };79
var onsuccess = Function.createDelegate(this, this._onsuccess);80
var onfailure = Function.createDelegate(this, this._onfailure);81
Sys.Net.WebServiceProxy.invoke(this.get_ServicePath(), this.get_ServiceMethod(), false, params, onsuccess, onfailure);82
},83

_onsuccess: function(e)
{84
this.ClearItems();85

86
this.get_element().value = "";87

for (var i = 0; i < e.length; i++)
{88
if (e[i].isDefaultValue)89
this.AddOption(e[i].Name, e[i].Value, true);90
else91
this.AddOption(e[i].Name, e[i].Value);92
}93

94
this.Enable();95

96
if (this.get_element()._childListBox)97
this.get_element()._childListBox._onParentChange();98
},99

_onfailure: function(e)
{100
alert(this.get_name() + "在对象" + this.ClientID + "上的错误\n\n错误代码:" + e._statusCode + "\n详细信息:" + e._message + "\n" + e._stackTrace);101
},102

initialize: function()
{103
Yinxin_WebControls.CascadingListBoxBehavior.callBaseMethod(this, 'initialize');104
// 在此处添加自定义初始化105
this.ClientID = this.get_element().id;106

107
this.ClearItems();108

109
this.AddOption(this._EmptyText, "");110

111
this.get_element().disabled = 'disabled';112

113

if (this._ParentControlID != null)
{114
this._ParentElement = $get(this._ParentControlID);115
this._ParentElement._childListBox = this;116
var changeHandler = Function.createDelegate(this, this._onParentChange);117
$addHandler(this._ParentElement, "change", changeHandler);118
}119

else
{120
this._onParentChange(null, true);121
}122
},123

dispose: function()
{124
//在此处添加自定义释放操作125
$clearHandlers(this.get_element());126
Yinxin_WebControls.CascadingListBoxBehavior.callBaseMethod(this, 'dispose');127
}128
}129
Yinxin_WebControls.CascadingListBoxBehavior.registerClass('Yinxin_WebControls.CascadingListBoxBehavior', Sys.UI.Behavior);130

131
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();132

最后把脚本注册为资源就OK了
1
//加入这句
2
[assembly: System.Web.UI.WebResource("yixin_webcontrols.CascadingListBoxBehavior.js","text/javascript")]
//加入这句2
[assembly: System.Web.UI.WebResource("yixin_webcontrols.CascadingListBoxBehavior.js","text/javascript")]
使用事例:
1
//web服务2
using System;3
using System.Web;4
using System.Collections;5
using System.Web.Services;6
using System.Web.Services.Protocols;7
using DWZ_DAL.Xml;8
using DWZ_Entity.Xml;9
using yixin_webcontrols;10

11

12

/**//// <summary>13
/// ClassService 的摘要说明14
/// </summary>15
[WebService(Namespace = "http://tempuri.org/")]16
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]17
[System.Web.Script.Services.ScriptService]18
public class ClassService : System.Web.Services.WebService19


{20
[WebMethod]21
public CascadingListBoxNameValue[] GetClasses(string knownCategoryValues, string category)22

{23
//knownCategoryValues:父ListBox选中的value24
//category:当前ListBox所属分类25

26
CascadingListBoxNameValue[] cddnv;27
switch (category)28

{ 29
case "Classes":30
//cddnv[0] = new CascadingListBoxNameValue(Name,Id);31
//cddnv[1] = new CascadingListBoxNameValue(Name,Id);32
//其他操作
33
break;34
default:35
//cddnv[0] = new CascadingListBoxNameValue("未定义的category:" + category, "-1");36
break;37
}38
return cddnv;39
}40
}41

42

然后在页面上使用控件:
<%@ Register Assembly="yixin_webcontrols2.0" Namespace="yixin_webcontrols" TagPrefix="cc3" %>
<asp:ListBox ID="ListBox1" runat="server" Height="300px" Width="140px"></asp:ListBox>
<cc3:CascadingListBox ID="CascadingListBox1" Category="BigClass" EmptyText="" TargetControlID="ListBox1" ServiceMethod="GetClasses" ServicePath="../Service/ClassService.asmx" runat="server" />
<asp:ListBox ID="ListBox2" runat="server" Height="300px" Width="140px"></asp:ListBox>
<cc3:CascadingListBox ID="CascadingListBox2" Category="Classes" EmptyText="请选择大分类" TargetControlID="ListBox2" ParentControlID="ListBox1" ServiceMethod="GetClasses" ServicePath="../Service/ClassService.asmx" runat="server" />
<asp:ListBox ID="ListBox3" runat="server" Height="300px" Width="140px"></asp:ListBox>
<cc3:CascadingListBox ID="CascadingListBox3" Category="Class" EmptyText="请选择一级分类" TargetControlID="ListBox3" ParentControlID="ListBox2" ServiceMethod="GetClasses" ServicePath="../Service/ClassService.asmx" runat="server" />
浙公网安备 33010602011771号