| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /* System.Web.UI.HtmlControls
- * Authors
- * Leen Toelen ([email protected])
- */
- using System;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Web.Util;
- using System.Globalization;
- using System.ComponentModel;
- using System.Collections;
- using System.Collections.Specialized;
- namespace System.Web.UI.HtmlControls{
-
- [ControlBuilder (typeof (HtmlSelectBuilder))]
- [DefaultEvent("ServerChange")]
- [ValidationProperty("Value")]
- public class HtmlSelect : HtmlContainerControl, IPostBackDataHandler{
-
-
- private int _cachedSelectedIndex;
- private object _dataSource;
- private static readonly object EventServerChange = new object ();
- private ListItemCollection _items;
-
- public HtmlSelect():base("select"){
- _cachedSelectedIndex = -1;
- }
-
- protected override void AddParsedSubObject(object obj){
- if (obj as ListItem != null) {
- this.Items.Add((ListItem) obj);
- return;
- }
- throw new HttpException("HtmlSelect cannot have children of Type " + obj.GetType().Name);
- }
-
- protected virtual void ClearSelection()
- {
- foreach (ListItem item in Items)
- item.Selected = false;
- }
-
- protected override ControlCollection CreateControlCollection(){
- return new EmptyControlCollection(this);
- }
- protected override void LoadViewState(object savedState)
- {
- if (savedState != null) {
- Triplet state = (Triplet) savedState;
- base.LoadViewState (state.First);
- Items.LoadViewState (state.Second);
- object indices = state.Third;
- if (indices != null)
{
- Select ((int []) indices);
- }
- }
- }
-
- protected override void OnDataBinding (EventArgs e)
- {
- base.OnDataBinding (e);
- IEnumerable resolvedDataSource = DataSourceHelper.GetResolvedDataSource (DataSource, DataMember);
- if (resolvedDataSource != null) {
- string text = DataTextField;
- string value = DataValueField;
- Items.Clear();
- ICollection rdsCollection = resolvedDataSource as ICollection;
- if (rdsCollection != null)
- Items.Capacity = rdsCollection.Count;
- bool valid = false;
- if (text.Length > 0 && value.Length > 0)
- valid = true;
- foreach (object current in resolvedDataSource) {
- ListItem li = new ListItem ();
- if (valid == true){
- if (text.Length > 0)
- li.Text = DataBinder.GetPropertyValue (current, text, null);
- if (value.Length > 0)
- li.Value = DataBinder.GetPropertyValue (current, value, null);
- } else {
- li.Value = li.Text = current.ToString();
- }
- Items.Add (li);
- }
- }
- if (_cachedSelectedIndex != -1) {
- SelectedIndex = _cachedSelectedIndex;
- _cachedSelectedIndex = -1;
- }
- }
-
- protected override void OnPreRender(EventArgs e){
- if (Page != null && Size >= 0 && !Disabled){
- Page.RegisterRequiresPostBack(this);
- }
- }
-
- protected virtual void OnServerChange(EventArgs e){
- EventHandler handler = (EventHandler) Events[EventServerChange];
- if (handler != null)
- handler (this,e);
- }
-
- protected override void RenderAttributes(HtmlTextWriter writer){
- writer.WriteAttribute("name", Name);
- Attributes.Remove("name");
- Attributes.Remove("DataValueField");
- Attributes.Remove("DataTextField");
- Attributes.Remove("DataMember");
- base.RenderAttributes(writer);
- }
-
- protected override void RenderChildren(HtmlTextWriter writer){
- //flush output
- writer.WriteLine();
- // increase indent level, improves readability
- writer.Indent = writer.Indent + 1;
- if (Items.Count >= 0){
- // display all options, and set the selected option
- bool rendered_selected = false;
- foreach (ListItem option in Items){
- //write begin tag with attributes
- writer.WriteBeginTag("option");
- if (!rendered_selected && option.Selected){
- writer.WriteAttribute("selected","selected");
- if (!Multiple)
- rendered_selected = true;
- }
- else if (option.Selected){
- option.Selected = false;
- }
- writer.WriteAttribute("value",option.Value,true);
- option.Attributes.Remove("text");
- option.Attributes.Remove("value");
- option.Attributes.Remove("selected");
- option.Attributes.Render(writer);
- writer.Write('>');
- //write the option text
- HttpUtility.HtmlEncode(option.Text, writer);
- //close the current option tag
- writer.WriteEndTag("option");
- //flush output
- writer.WriteLine();
- }
- }
- // set the indent level back to normal
- writer.Indent = writer.Indent - 1;
- }
-
- protected override object SaveViewState ()
- {
- object baseViewState = base.SaveViewState ();
- object itemsViewState = Items.SaveViewState ();
- object indices = null;
- if (Events[EventServerChange] != null || !Disabled || Visible)
- indices = SelectedIndices;
- if (indices != null || baseViewState != null || itemsViewState != null)
- return new Triplet (baseViewState, itemsViewState, indices);
- return null;
- }
-
- protected virtual void Select(int[] selectedIndices){
- // unselect all options
- ClearSelection();
- // iterate through options, and set when selected
- foreach (int current in selectedIndices){
- if (current >= 0 && current < Items.Count){
- Items[current].Selected = true;
- }
- }
- }
-
- bool IPostBackDataHandler.LoadPostData (string postDataKey,
- NameValueCollection postCollection)
- {
- //get the posted selectedIndices[]
- string [] postedValueColl = postCollection.GetValues(postDataKey);
- bool changed = false;
- if (postedValueColl != null){
- if (!Multiple){
- //single selection
- //int postedValue = Items.FindIndexByValue(postedValueColl[0]);
- int postedValue = Items.IndexOf(Items.FindByValue(postedValueColl[0]));
- if (postedValue != SelectedIndex){
- //set the SelectedIndex
- SelectedIndex = postedValue;
- changed = true;
- }
- }
- else{
- //multiple selection
- int postedValueCount = postedValueColl.Length;
- int[] arr= new int[postedValueCount];
- //fill an array with the posted Values
- for (int i = 0; i <= postedValueCount; i++)
- arr[i] = Items.IndexOf(Items.FindByValue(postedValueColl[i]));
- //test if everything went fine
- if( postedValueCount == SelectedIndices.Length)
- for (int i = 0; i <= postedValueCount; i++)
- if(arr[i] == SelectedIndices[i])
- changed = true;
- else
- changed = true;
- //commit the posted Values
- if(changed)
- Select(arr);
- }
- }
- else if (SelectedIndex != -1){
- SelectedIndex = -1;
- changed = true;
- }
- return changed;
- }
-
- void IPostBackDataHandler.RaisePostDataChangedEvent ()
- {
- OnServerChange (EventArgs.Empty);
- }
-
- //starts tracking changes to the viewstate
- protected override void TrackViewState(){
- base.TrackViewState();
- Items.TrackViewState();
- }
-
- [WebCategory("Action")]
- [WebSysDescription("Fires when the selection changes.")]
- public event EventHandler ServerChange{
- add{
- Events.AddHandler(EventServerChange, value);
- }
- remove{
- Events.RemoveHandler(EventServerChange, value);
- }
- }
-
- [DefaultValue("")]
- [WebCategory("Data")]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [WebSysDescription("The data member of the select.")]
- public virtual string DataMember{
- get{
- object viewStateDataMember = ViewState["DataMember"];
- if ( viewStateDataMember != null) return (String) viewStateDataMember;
- return String.Empty;
- }
- set{
- Attributes["DataMember"] = HtmlControl.AttributeToString(value);
- }
- }
-
- [DefaultValue(null)]
- [WebCategory("Data")]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [WebSysDescription("The data source used to populate the list with data.")]
- public virtual object DataSource{
- get{
- return _dataSource;
- }
- set{
- if (value != null && !(value is IListSource)) {
- if (!(value is IEnumerable))
- throw new ArgumentException ("Invalid dataSource type");
- }
- _dataSource = value;
- }
- }
-
- [DefaultValue("")]
- [WebCategory("Data")]
- [WebSysDescription("The field in the data source that provides the item value.")]
- public virtual string DataTextField{
- get{
- string attr = Attributes["DataTextField"];
- if (attr != null){
- return attr;
- }
- return String.Empty;
- }
- set{
- Attributes["DataTextField"] = AttributeToString(value);
- }
- }
-
- [DefaultValue("")]
- [WebCategory("Data")]
- [WebSysDescription("The field in the data source that provides the item value.")]
- public virtual string DataValueField{
- get{
- string attr = Attributes["DataValueField"];
- if (attr != null)return attr;
- return String.Empty;
- }
- set{
- Attributes["DataValueField"] = AttributeToString(value);
- }
- }
-
- public override string InnerHtml{
- get{
- throw new NotSupportedException("InnerHtml is not supported by " + this.GetType().Name);
- }
- set{
- throw new NotSupportedException("InnerHtml is not supported by " + this.GetType().Name);
- }
- }
-
- public override string InnerText{
- get{
- throw new NotSupportedException("InnerText is not supported by " + this.GetType().Name);
- }
- set{
- throw new NotSupportedException("InnerText is not supported by " + this.GetType().Name);
- }
- }
-
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public ListItemCollection Items{
- get{
- if (_items == null){
- _items = new ListItemCollection();
- if (IsTrackingViewState) _items.TrackViewState();
- }
- return _items;
- }
- }
-
- [DefaultValue("")]
- [WebCategory("Behavior")]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public bool Multiple{
- get{
- string attr = Attributes["multiple"];
- if (attr != null) return (0 == String.Compare (attr, "true", true));
- return false;
- }
- set{
- Attributes["multiple"] = value.ToString ();
- }
- }
-
- [DefaultValue("")]
- [WebCategory("Behavior")]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public string Name{
- get{
- return UniqueID;
- }
- set{
- //LAMESPEC
- return;
- }
- }
- [HtmlControlPersistable (false)]
- [Browsable(false)]
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public virtual int SelectedIndex {
- get{
- for (int i=0; i<Items.Count; i++){
- if (Items[i].Selected == true) return i;
- }
- if (Size<=1 && !Multiple){
- if(Items.Count > 0) Items[0].Selected = true;
- return 0;
- }
- return -1;
- }
- set{
- if(Items.Count == 0){
- _cachedSelectedIndex = value;
- return;
- }
- if (value < -1 || value >= Items.Count)
- throw new ArgumentOutOfRangeException();
- ClearSelection();
- if (value >= 0)
- Items[value].Selected = true;
- }
- }
-
- protected virtual int[] SelectedIndices {
- get{
- int[] indices = new int[3];
- int indicesCount = 0;
- for(int i=0; i < Items.Count; i++){
- if (Items[i].Selected){
- if( indicesCount == (int) indices.Length){
- int[] temp = new int[indicesCount + indicesCount];
- indices.CopyTo(temp,0);
- indices = temp;
- }
- indices[indicesCount] = i;
- indicesCount++;
- }
- }
- int[] arr = new int[indicesCount];
- System.Array.Copy(indices,0,arr,0,indicesCount);
- return arr;
- }
- }
-
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public int Size{
- get{
- string attr = Attributes["size"];
- if (attr != null){
- return Int32.Parse(attr, CultureInfo.InvariantCulture);;
- }
- return -1;
- }
- set{
- Attributes["size"] = AttributeToString(value);
- }
- }
-
- [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public string Value {
- get{
- int selectedIndex = SelectedIndex;
- if (selectedIndex >=0 && selectedIndex < Items.Count){
- return Items[selectedIndex].Value;
- }
- return String.Empty;
- }
- set{
- int findValue = Items.IndexOf(Items.FindByValue(value));
- if (findValue >= 0) SelectedIndex = findValue;
- }
- }
-
- } // class HtmlSelect
- } // namespace System.Web.UI.HtmlControls
|