最近在项目中,要实现对DropDownList中的Option进行分组的功能。大家都知道传统的DropDownList是无法实现,以及对DropDownList的排序问题。所以么法子啊, I make my own.
效果图:

代码如下:


















































1
DDL 控件类:
2
3
public class DDL : DropDownList
4
{
5
private const String OPTIONGROUP = "optgroup";
6
private const String OPTIONID = "id";
7
private const String OPTION = "option";
8
private const String LABEL = "label";
9
private const String VALUE = "value";
10
private const String SELECTED = "selected";
11
12
//over write RenderContents
13
protected override void RenderContents(HtmlTextWriter writer)
14
{
15
String optgroup = String.Empty;
16
String id = String.Empty;
17
18
ArrayList optOptionGroups = new ArrayList();
19
20
foreach (ListItem item in this.Items)
21
{
22
if (item.Attributes[OPTIONGROUP] == null)
23
{
24
RenderListItem(item, writer);
25
}
26
else
27
{
28
optgroup = item.Attributes[OPTIONGROUP];
29
id = item.Attributes[OPTIONID];
30
31
if (optOptionGroups.Contains(optgroup))
32
{
33
RenderListItem(item, writer);
34
}
35
else
36
{
37
if (optOptionGroups.Count > 0)
38
{
39
optgroupEndTag(writer);
40
}
41
optgroupBeginTag(id, optgroup, writer);
42
optOptionGroups.Add(optgroup);
43
}
44
}
45
}
46
47
if (optOptionGroups.Count > 0)
48
{
49
optgroupEndTag(writer);
50
}
51
}
52
53
54
/// <summary>
55
/// Render List Item
56
/// </summary>
57
/// <param name="item"></param>
58
/// <param name="writer"></param>
59
private void RenderListItem(ListItem item, HtmlTextWriter writer)
60
{
61
writer.WriteBeginTag(OPTION);
62
writer.WriteAttribute(VALUE, item.Value, true);
63
64
if (item.Selected)
65
{
66
writer.WriteAttribute(SELECTED, SELECTED, false);
67
}
68
69
foreach (String key in item.Attributes.Keys)
70
{
71
writer.WriteAttribute(key, item.Attributes[key]);
72
}
73
74
writer.Write(HtmlTextWriter.TagRightChar);
75
HttpUtility.HtmlEncode(item.Text, writer);
76
writer.WriteEndTag(OPTION);
77
writer.WriteLine();
78
}
79
80
//选项添加到组中
81
private void optgroupBeginTag(String id, String name, HtmlTextWriter writer)
82
{
83
writer.WriteBeginTag(OPTIONGROUP);
84
writer.WriteAttribute(LABEL, name);
85
writer.WriteAttribute(OPTIONID, id);
86
writer.Write(HtmlTextWriter.TagRightChar);
87
writer.WriteLine();
88
}
89
90
private void optgroupEndTag(HtmlTextWriter writer)
91
{
92
writer.WriteEndTag(OPTIONGROUP);
93
writer.WriteLine();
94
}
95
96
/// <summary>
97
/// 对ListItem进行排序[顺序排序]
98
/// </summary>
99
/// <param name="sortBy"></param>
100
/// <param name="dropDownList"></param>
101
public void SortListItem(DropDownList dropDownList, String sortBy, Boolean sortType)
102
{
103
ListItem[] listItem = new ListItem[dropDownList.Items.Count];
104
105
dropDownList.Items.CopyTo(listItem, 0);
106
107
if (!sortBy.Equals(String.Empty))
108
{
109
Array.Sort(listItem, new ListItemTextComparer());
110
}
111
else
112
{
113
Array.Sort(listItem, new ListItemValueComparer());
114
115
}
116
if (!sortType)
117
{
118
Array.Reverse(listItem);
119
}
120
121
dropDownList.Items.Clear();
122
dropDownList.Items.AddRange(listItem);
123
}
124
125
/// <summary>
126
/// 按ListItem的Text或者Value进行排序
127
/// </summary>
128
internal class ListItemTextComparer : IComparer
129
{
130
public int Compare(object x, object y)
131
{
132
return new CaseInsensitiveComparer().Compare((x as ListItem).Text, (y as ListItem).Text);
133
}
134
}
135
136
/// <summary>
137
/// 按ListItem的Value进行排序
138
/// </summary>
139
internal class ListItemValueComparer : IComparer
140
{
141
public int Compare(object x, object y)
142
{
143
return new CaseInsensitiveComparer().Compare((x as ListItem).Value, (y as ListItem).Value);
144
}
145
}
146
}

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146
