2006-09-20 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / ListControl.cs
index ec82c8433d8b010f1739c1c02a25faeeacd27c83..acf4c7c8aefce247336f59936db0335992b6d66a 100644 (file)
@@ -42,11 +42,9 @@ namespace System.Web.UI.WebControls {
        [DefaultPropertyAttribute ("DataSource")]
 #endif
        [Designer("System.Web.UI.Design.WebControls.ListControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
+       [ParseChildrenAttribute (true, "Items")]
 #if NET_2_0
        [ControlValueProperty ("SelectedValue", null)]
-       [ParseChildrenAttribute (true, "Items", ChildControlType = typeof (Control))]
-#else
-       [ParseChildrenAttribute (true, "Items")]
 #endif 
        public abstract class ListControl :
 #if NET_2_0
@@ -62,6 +60,8 @@ namespace System.Web.UI.WebControls {
 #endif
 
                private ListItemCollection items;
+               int saved_selected_index = -2;
+               string saved_selected_value;
                
                public ListControl () : base (HtmlTextWriterTag.Select)
                {
@@ -113,7 +113,13 @@ namespace System.Web.UI.WebControls {
                [WebCategory ("Data")]
                public virtual object DataSource {
                        get { return data_source; }
-                       set { data_source = value; }
+                       set { 
+                               if(value == null || value is IListSource || value is IEnumerable) { 
+                                       data_source = value;
+                                       return;
+                               }
+                               throw new ArgumentException("Invalid DataSource Type");
+                       }
                }
 #endif         
 
@@ -188,11 +194,20 @@ namespace System.Web.UI.WebControls {
                                return -1;
                        }
                        set {
-                               ClearSelection ();
-                               if (value == -1 || items == null)
+                               if (items == null || items.Count == 0) {
+                                       // This will happen when assigning this property
+                                       // before DataBind () is called on the control.
+                                       saved_selected_index = value;
                                        return;
-                               if (value < 0 || value >= Items.Count)
+                               }
+
+                               if (value < -1 || value >= Items.Count)
                                        throw new ArgumentOutOfRangeException ("value");
+
+                               ClearSelection ();
+                               if (value == -1)
+                                       return;
+
                                items [value].Selected = true;
 
                                /* you'd think this would be called, but noooo */
@@ -234,9 +249,26 @@ namespace System.Web.UI.WebControls {
                        }
                        set {
                                ClearSelection ();
-                               for (int i = 0; i < Items.Count; i++) {
-                                       if (Items [i].Value == value)
-                                               Items [i].Selected = true;
+                               if (items == null || items.Count == 0) {
+                                       // This will happen when assigning this property
+                                       // before DataBind () is called on the control.
+                                       saved_selected_value = value;
+                                       return;
+                               }
+
+                               int count = Items.Count;
+                               ListItemCollection coll = Items;
+                               bool thr = true;
+                               for (int i = 0; i < count; i++) {
+                                       if (coll [i].Value == value) {
+                                               coll [i].Selected = true;
+                                               thr = false;
+                                       }
+                               }
+
+                               if (thr) {
+                                       string msg = String.Format ("Argument value is out of range: {0}", value);
+                                       throw new ArgumentOutOfRangeException (msg);
                                }
                        }
                }
@@ -289,27 +321,6 @@ namespace System.Web.UI.WebControls {
                                items [i].Selected = false;
                }
 
-#if NET_2_0
-               protected internal override void LoadControlState (object savedState)
-               {
-                       object first = null;
-                       ArrayList indices = null;
-                       Pair pair = savedState as Pair;
-
-                       if (pair != null) {
-                               first = pair.First;
-                               indices = pair.Second as ArrayList;
-                       }
-
-                       base.LoadControlState (first);
-
-                       if (indices != null) {
-                               foreach (int index in indices)
-                                       Items [index].Selected = true;
-                       }
-               }
-#endif         
-
                protected override void OnDataBinding (EventArgs e)
                {
                        base.OnDataBinding (e);
@@ -318,48 +329,24 @@ namespace System.Web.UI.WebControls {
                        if (list == null)
                                return;
 
-                       Items.Clear ();
-
-                       foreach (object container in list) {
-                               string text;
-                               string value;
-
-                               if (DataTextField != String.Empty) {
-                                       text = DataBinder.Eval (container,
-                                                       DataTextField).ToString ();
-                               } else {
-                                       text = String.Empty;
-                               }
-
-                               if (DataValueField != String.Empty) {
-                                       value = DataBinder.Eval (container,
-                                                       DataValueField).ToString ();
-                               } else {
-                                       value = text;
-                               }
-
-                               if (text == String.Empty) {
-                                       if (value != String.Empty)
-                                               text = value;
-                               } else if (DataTextFormatString != String.Empty) {
-                                       // Dont apply the format string if we don't actually 
-                                       // have a textfield
-                                       text = String.Format (DataTextFormatString, text);
-                               }
+#if NET_2_0
+                       if (!AppendDataBoundItems)
+#endif
+                               Items.Clear();
 
-                               ListItem item = new ListItem (text, value);
-                               Items.Add (item);
+#if !NET_2_0
+                       DoDataBinding (list);
+#endif
+                       if (saved_selected_value != null) {
+                               SelectedValue = saved_selected_value;
+                               if (saved_selected_index != -2 && saved_selected_index != SelectedIndex)
+                                       throw new ArgumentException ("SelectedIndex and SelectedValue are mutually exclusive.");
+                       } else if (saved_selected_index != -2) {
+                               SelectedIndex = saved_selected_index;
+                               // No need to check saved_selected_value here, as it's done before.
                        }
                }
 
-#if NET_2_0
-               protected internal override void OnInit (EventArgs e)
-               {
-                       Page.RegisterRequiresControlState (this);
-                       base.OnInit (e);
-               }
-#endif         
-
 #if NET_2_0
                protected internal
 #else          
@@ -370,6 +357,43 @@ namespace System.Web.UI.WebControls {
                        base.OnPreRender (e);
                }
 
+               void DoDataBinding (IEnumerable dataSource)
+               {
+                       if (dataSource != null) {
+                               string format = DataTextFormatString;
+                               if (format == "")
+                                       format = null;
+
+                               string text_field = DataTextField;
+                               string value_field = DataValueField;
+                               ListItemCollection coll = Items;
+                               foreach (object container in dataSource) {
+                                       string text;
+                                       string val;
+
+                                       text = val = null;
+                                       if (text_field != "") {
+                                               text = DataBinder.GetPropertyValue (container, text_field, format);
+                                       }
+
+                                       if (value_field != "") {
+                                               val = DataBinder.GetPropertyValue (container, value_field).ToString ();
+                                       } else if (text_field == "") {
+                                               text = val = container.ToString ();
+                                               if (format != null)
+                                                       text = String.Format (format, container);
+                                       } else if (text != null) {
+                                               val = text;
+                                       }
+
+                                       if (text == null)
+                                               text = val;
+
+                                       coll.Add (new ListItem (text, val));
+                               }
+                       }
+               }
+
 #if NET_2_0
                protected virtual void OnTextChanged (EventArgs e)
                {
@@ -378,16 +402,17 @@ namespace System.Web.UI.WebControls {
                                handler (this, e);
                }
 
-               [MonoTODO]
                protected internal override void PerformDataBinding (IEnumerable dataSource)
                {
-                       throw new NotImplementedException ();
+                       base.PerformDataBinding (dataSource);
+
+                       DoDataBinding (dataSource);
                }
 
-               [MonoTODO]
+               [MonoTODO ("why override?")]
                protected override void PerformSelect ()
                {
-                       throw new NotImplementedException ();
+                       base.PerformSelect ();
                }
 
                [MonoTODO]
@@ -396,21 +421,9 @@ namespace System.Web.UI.WebControls {
                        base.RenderContents (w);
                }
 
-               protected internal override object SaveControlState ()
-               {
-                       object first;
-                       ArrayList second;
-
-                       first = base.SaveControlState ();
-                       second = GetSelectedIndices();
-                       if (second == null)
-                               second = new ArrayList();
-
-                       return new Pair (first, second);
-               }
 #endif         
 
-               ArrayList GetSelectedIndices ()
+               internal ArrayList GetSelectedIndicesInternal ()
                {
                        ArrayList selected = null;
                        if (items != null) {
@@ -435,46 +448,26 @@ namespace System.Web.UI.WebControls {
                        if (manager != null)
                                second = manager.SaveViewState ();
 
-#if !NET_2_0
-                       ArrayList selected = GetSelectedIndices ();
-#endif
+                       ArrayList selected = GetSelectedIndicesInternal ();
 
-                       if (first == null && second == null
-#if !NET_2_0
-                           && selected == null
-#endif
-                           )
+                       if (first == null && second == null && selected == null)
                                return null;
 
-#if NET_2_0
-                       return new Pair (first, second);
-#else
                        return new Triplet (first, second, selected);
-#endif
                }
 
                protected override void LoadViewState (object savedState)
                {
                        object first = null;
                        object second = null;
-#if !NET_2_0
                        ArrayList indices = null;
-#endif
 
-#if NET_2_0
-                       Pair pair = savedState as Pair;
-                       if (pair != null) {
-                               first = pair.First;
-                               second = pair.Second;
-                       }
-#else
                        Triplet triplet = savedState as Triplet;
                        if (triplet != null) {
                                first = triplet.First;
                                second = triplet.Second;
                                indices = triplet.Third as ArrayList;
                        }
-#endif
 
                        base.LoadViewState (first);
 
@@ -483,12 +476,10 @@ namespace System.Web.UI.WebControls {
                                manager.LoadViewState (second);
                        }
 
-#if !NET_2_0
                        if (indices != null) {
                                foreach (int index in indices)
                                        Items [index].Selected = true;
                        }
-#endif
                }
 
 #if NET_2_0
@@ -539,31 +530,30 @@ namespace System.Web.UI.WebControls {
                }
                
                
-               [MonoTODO]
                [Themeable (false)]
                [DefaultValue (false)]
                [WebSysDescription ("")]
                [WebCategory ("Behavior")]
-               public virtual bool CausesValidation {
+               public virtual bool CausesValidation {
                        get {
-                               throw new NotImplementedException ();
+                               return ViewState.GetBool ("CausesValidation", false);
                        }
+
                        set {
-                               throw new NotImplementedException ();   
+                               ViewState ["CausesValidation"] = value;
                        }
                }
 
-               [MonoTODO]
                [Themeable (false)]
                [DefaultValue ("")]
                [WebSysDescription ("")]
                [WebCategoryAttribute ("Behavior")]
                public virtual string ValidationGroup {
                        get {
-                               throw new NotImplementedException ();
+                               return ViewState.GetString ("ValidationGroup", "");
                        }
                        set {
-                               throw new NotImplementedException ();
+                               ViewState ["ValidationGroup"] = value;
                        }
                }