(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.Web / System.Web.UI.HtmlControls / HtmlSelect.cs
blob24c5b50e0d7de26b88c589e85aa98ddfa2d30c1f
1 /* System.Web.UI.HtmlControls
2 * Authors
3 * Leen Toelen (toelen@hotmail.com)
4 */
6 using System;
7 using System.Web;
8 using System.Web.UI;
9 using System.Web.UI.WebControls;
10 using System.Web.Util;
11 using System.Globalization;
12 using System.ComponentModel;
13 using System.Collections;
14 using System.Collections.Specialized;
16 namespace System.Web.UI.HtmlControls{
18 [ControlBuilder (typeof (HtmlSelectBuilder))]
19 [DefaultEvent("ServerChange")]
20 [ValidationProperty("Value")]
21 public class HtmlSelect : HtmlContainerControl, IPostBackDataHandler{
24 private int _cachedSelectedIndex;
25 private object _dataSource;
26 private static readonly object EventServerChange = new object ();
27 private ListItemCollection _items;
29 public HtmlSelect():base("select"){
30 _cachedSelectedIndex = -1;
33 protected override void AddParsedSubObject(object obj){
34 if (obj as ListItem != null) {
35 this.Items.Add((ListItem) obj);
36 return;
38 throw new HttpException("HtmlSelect cannot have children of Type " + obj.GetType().Name);
41 protected virtual void ClearSelection()
43 foreach (ListItem item in Items)
44 item.Selected = false;
47 protected override ControlCollection CreateControlCollection(){
48 return new EmptyControlCollection(this);
51 protected override void LoadViewState(object savedState)
53 if (savedState != null) {
54 Triplet state = (Triplet) savedState;
55 base.LoadViewState (state.First);
56 Items.LoadViewState (state.Second);
57 object indices = state.Third;
58 if (indices != null) {
59 Select ((int []) indices);
64 protected override void OnDataBinding (EventArgs e)
66 base.OnDataBinding (e);
67 IEnumerable resolvedDataSource = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
68 if (resolvedDataSource != null) {
69 string text = DataTextField;
70 string value = DataValueField;
71 Items.Clear();
73 ICollection rdsCollection = resolvedDataSource as ICollection;
74 if (rdsCollection != null)
75 Items.Capacity = rdsCollection.Count;
77 bool valid = false;
78 if (text.Length > 0 && value.Length > 0)
79 valid = true;
81 foreach (object current in resolvedDataSource) {
82 ListItem li = new ListItem ();
83 if (valid == true){
84 if (text.Length > 0)
85 li.Text = DataBinder.GetPropertyValue (current, text, null);
86 if (value.Length > 0)
87 li.Value = DataBinder.GetPropertyValue (current, value, null);
88 } else {
89 li.Value = li.Text = current.ToString();
92 Items.Add (li);
96 if (_cachedSelectedIndex != -1) {
97 SelectedIndex = _cachedSelectedIndex;
98 _cachedSelectedIndex = -1;
102 protected override void OnPreRender(EventArgs e){
103 if (Page != null && Size >= 0 && !Disabled){
104 Page.RegisterRequiresPostBack(this);
108 protected virtual void OnServerChange(EventArgs e){
109 EventHandler handler = (EventHandler) Events[EventServerChange];
110 if (handler != null)
111 handler (this,e);
114 protected override void RenderAttributes(HtmlTextWriter writer){
115 writer.WriteAttribute("name", Name);
116 Attributes.Remove("name");
117 Attributes.Remove("DataValueField");
118 Attributes.Remove("DataTextField");
119 Attributes.Remove("DataMember");
120 base.RenderAttributes(writer);
123 protected override void RenderChildren(HtmlTextWriter writer){
124 //flush output
125 writer.WriteLine();
126 // increase indent level, improves readability
127 writer.Indent = writer.Indent + 1;
128 if (Items.Count >= 0){
129 // display all options, and set the selected option
130 bool rendered_selected = false;
131 foreach (ListItem option in Items){
132 //write begin tag with attributes
133 writer.WriteBeginTag("option");
134 if (!rendered_selected && option.Selected){
135 writer.WriteAttribute("selected","selected");
136 if (!Multiple)
137 rendered_selected = true;
139 else if (option.Selected){
140 option.Selected = false;
143 writer.WriteAttribute("value",option.Value,true);
144 option.Attributes.Remove("text");
145 option.Attributes.Remove("value");
146 option.Attributes.Remove("selected");
147 option.Attributes.Render(writer);
148 writer.Write('>');
149 //write the option text
150 HttpUtility.HtmlEncode(option.Text, writer);
151 //close the current option tag
152 writer.WriteEndTag("option");
153 //flush output
154 writer.WriteLine();
157 // set the indent level back to normal
158 writer.Indent = writer.Indent - 1;
161 protected override object SaveViewState ()
163 object baseViewState = base.SaveViewState ();
164 object itemsViewState = Items.SaveViewState ();
165 object indices = null;
167 if (Events[EventServerChange] != null || !Disabled || Visible)
168 indices = SelectedIndices;
170 if (indices != null || baseViewState != null || itemsViewState != null)
171 return new Triplet (baseViewState, itemsViewState, indices);
173 return null;
176 protected virtual void Select(int[] selectedIndices){
177 // unselect all options
178 ClearSelection();
179 // iterate through options, and set when selected
180 foreach (int current in selectedIndices){
181 if (current >= 0 && current < Items.Count){
182 Items[current].Selected = true;
187 bool IPostBackDataHandler.LoadPostData (string postDataKey,
188 NameValueCollection postCollection)
190 //get the posted selectedIndices[]
191 string [] postedValueColl = postCollection.GetValues(postDataKey);
192 bool changed = false;
193 if (postedValueColl != null){
194 if (!Multiple){
195 //single selection
196 //int postedValue = Items.FindIndexByValue(postedValueColl[0]);
197 int postedValue = Items.IndexOf(Items.FindByValue(postedValueColl[0]));
198 if (postedValue != SelectedIndex){
199 //set the SelectedIndex
200 SelectedIndex = postedValue;
201 changed = true;
204 else{
205 //multiple selection
206 int postedValueCount = postedValueColl.Length;
207 int[] arr= new int[postedValueCount];
208 //fill an array with the posted Values
209 for (int i = 0; i < postedValueCount; i++)
210 arr[i] = Items.IndexOf(Items.FindByValue(postedValueColl[i]));
211 //test if everything went fine
212 if( postedValueCount == SelectedIndices.Length){
213 for (int i = 0; i < postedValueCount; i++)
214 if(arr[i] != SelectedIndices[i])
215 changed = true;
217 else
218 changed = true;
219 //commit the posted Values
220 if(changed)
221 Select(arr);
224 else if (SelectedIndex != -1){
225 SelectedIndex = -1;
226 changed = true;
228 return changed;
231 void IPostBackDataHandler.RaisePostDataChangedEvent ()
233 OnServerChange (EventArgs.Empty);
236 //starts tracking changes to the viewstate
237 protected override void TrackViewState(){
238 base.TrackViewState();
239 Items.TrackViewState();
242 [WebCategory("Action")]
243 [WebSysDescription("Fires when the selection changes.")]
244 public event EventHandler ServerChange{
245 add{
246 Events.AddHandler(EventServerChange, value);
248 remove{
249 Events.RemoveHandler(EventServerChange, value);
253 [DefaultValue("")]
254 [WebCategory("Data")]
255 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
256 [WebSysDescription("The data member of the select.")]
257 public virtual string DataMember{
258 get{
259 object viewStateDataMember = ViewState["DataMember"];
260 if ( viewStateDataMember != null) return (String) viewStateDataMember;
261 return String.Empty;
263 set{
264 Attributes["DataMember"] = HtmlControl.AttributeToString(value);
268 [DefaultValue(null)]
269 [WebCategory("Data")]
270 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
271 [WebSysDescription("The data source used to populate the list with data.")]
272 public virtual object DataSource{
273 get{
274 return _dataSource;
276 set{
277 if (value != null && !(value is IListSource)) {
278 if (!(value is IEnumerable))
279 throw new ArgumentException ("Invalid dataSource type");
281 _dataSource = value;
285 [DefaultValue("")]
286 [WebCategory("Data")]
287 [WebSysDescription("The field in the data source that provides the item value.")]
288 public virtual string DataTextField{
289 get{
290 string attr = Attributes["DataTextField"];
291 if (attr != null){
292 return attr;
294 return String.Empty;
296 set{
297 Attributes["DataTextField"] = AttributeToString(value);
301 [DefaultValue("")]
302 [WebCategory("Data")]
303 [WebSysDescription("The field in the data source that provides the item value.")]
304 public virtual string DataValueField{
305 get{
306 string attr = Attributes["DataValueField"];
307 if (attr != null)return attr;
308 return String.Empty;
310 set{
311 Attributes["DataValueField"] = AttributeToString(value);
315 public override string InnerHtml{
316 get{
317 throw new NotSupportedException("InnerHtml is not supported by " + this.GetType().Name);
319 set{
320 throw new NotSupportedException("InnerHtml is not supported by " + this.GetType().Name);
324 public override string InnerText{
325 get{
326 throw new NotSupportedException("InnerText is not supported by " + this.GetType().Name);
328 set{
329 throw new NotSupportedException("InnerText is not supported by " + this.GetType().Name);
333 [Browsable(false)]
334 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
335 public ListItemCollection Items{
336 get{
337 if (_items == null){
338 _items = new ListItemCollection();
339 if (IsTrackingViewState) _items.TrackViewState();
341 return _items;
345 [DefaultValue("")]
346 [WebCategory("Behavior")]
347 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
348 public bool Multiple{
349 get{
350 string attr = Attributes["multiple"];
351 if (attr != null) return (0 == String.Compare (attr, "true", true));
352 return false;
354 set{
355 Attributes["multiple"] = value.ToString ();
359 [DefaultValue("")]
360 [WebCategory("Behavior")]
361 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
362 public string Name{
363 get{
364 return UniqueID;
366 set{
367 //LAMESPEC
368 return;
372 [HtmlControlPersistable (false)]
373 [Browsable(false)]
374 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
375 public virtual int SelectedIndex {
376 get{
377 for (int i=0; i<Items.Count; i++){
378 if (Items[i].Selected == true) return i;
380 if (Size<=1 && !Multiple){
381 if(Items.Count > 0) Items[0].Selected = true;
382 return 0;
384 return -1;
386 set{
387 if(Items.Count == 0){
388 _cachedSelectedIndex = value;
389 return;
392 if (value < -1 || value >= Items.Count)
393 throw new ArgumentOutOfRangeException();
395 ClearSelection();
396 if (value >= 0)
397 Items[value].Selected = true;
401 protected virtual int[] SelectedIndices {
402 get{
403 int[] indices = new int[3];
404 int indicesCount = 0;
405 for(int i=0; i < Items.Count; i++){
406 if (Items[i].Selected){
407 if( indicesCount == (int) indices.Length){
408 int[] temp = new int[indicesCount + indicesCount];
409 indices.CopyTo(temp,0);
410 indices = temp;
412 indices[indicesCount] = i;
413 indicesCount++;
416 int[] arr = new int[indicesCount];
417 System.Array.Copy(indices,0,arr,0,indicesCount);
418 return arr;
422 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
423 public int Size{
424 get{
425 string attr = Attributes["size"];
426 if (attr != null){
427 return Int32.Parse(attr, CultureInfo.InvariantCulture);
429 return -1;
431 set{
432 Attributes["size"] = AttributeToString(value);
436 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
437 public string Value {
438 get{
439 int selectedIndex = SelectedIndex;
440 if (selectedIndex >=0 && selectedIndex < Items.Count){
441 return Items[selectedIndex].Value;
443 return String.Empty;
445 set{
446 int findValue = Items.IndexOf(Items.FindByValue(value));
447 if (findValue >= 0) SelectedIndex = findValue;
451 } // class HtmlSelect
452 } // namespace System.Web.UI.HtmlControls