// // System.Windows.Forms.ComboBox // // Author: // Joel Basson (jstrike@mweb.co.za) // Alberto Fernandez (infjaf00@yahoo.es) // // using System.Collections; using System.Drawing; using System.ComponentModel; using System.Runtime.InteropServices; namespace System.Windows.Forms { /// /// Represents a Windows ComboBox control. /// /// public class ComboBox: ListControl{ public ObjectCollection items; GLib.List list = new GLib.List (IntPtr.Zero, typeof (string)); System.Collections.ArrayList alist = new System.Collections.ArrayList(); private bool sorted = false; private int maxDropDownItems = 8; private ComboBoxStyle dropDownStyle = ComboBoxStyle.DropDown; private bool updating = false; private bool disableChanging = false; public ComboBox () : base (){ } protected override Size DefaultSize { get {return new Size (121, 20); } } [MonoTODO] public DrawMode DrawMode { get{return DrawMode.Normal;} set{ if (!Enum.IsDefined (typeof (DrawMode), value)) throw new InvalidEnumArgumentException ("DrawMode"); } } [MonoTODO] public ComboBoxStyle DropDownStyle { get{return dropDownStyle;} set{ if (!Enum.IsDefined (typeof(ComboBoxStyle), value)) throw new InvalidEnumArgumentException ("DropDownStyle"); if (dropDownStyle == value) return; switch (value){ case ComboBoxStyle.Simple: case ComboBoxStyle.DropDown: (Widget as Gtk.Combo).Entry.Editable = true; break; case ComboBoxStyle.DropDownList: (Widget as Gtk.Combo).Entry.Editable = false; break; } dropDownStyle = value; OnDropDownStyleChanged (EventArgs.Empty); } } [MonoTODO] public int DropDownWidth { get{ throw new NotImplementedException(); } set{ if (value < 1) throw new ArgumentException(); throw new NotImplementedException();} } [MonoTODO] public bool DroppedDown { get{ return false; } set{ return; } } [MonoTODO] public bool IntegralHeight { get{throw new NotImplementedException();} set{throw new NotImplementedException();} } [MonoTODO] public int ItemHeight { get{throw new NotImplementedException();} set{throw new NotImplementedException();} } public ComboBox.ObjectCollection Items{ get{ if (items == null) items = new ObjectCollection(this); return items; } } [MonoTODO] public int MaxDropDownItems { get{ return MaxDropDownItems; } set{ if ((value < 1) || (value > 100)) throw new ArgumentException(); maxDropDownItems = value; } } [MonoTODO] public int MaxLength { get{ return (Widget as Gtk.Combo).Entry.MaxLength; } set{ if (value < 0) value = 0; (Widget as Gtk.Combo).Entry.MaxLength = value; } } [MonoTODO] public int PreferredHeight { get{throw new NotImplementedException();} } [MonoTODO] public override int SelectedIndex{ get{ return Items.IndexOf(((Gtk.Combo)Widget).Entry.Text);} set{ if ((value < -2) || (value > Items.Count)) throw new ArgumentException ("SelectedIndex"); if (SelectedIndex == value) return; disableChanging = true; ((Gtk.Combo)Widget).Entry.Text = (string)Items [value]; OnSelectedIndexChanged(EventArgs.Empty); disableChanging = false; } } [MonoTODO] public Object SelectedItem{ get{ return Items[this.SelectedIndex];} set{ this.SelectedIndex = Items.IndexOf (value);} } [MonoTODO] public string SelectedText { get{ if (this.DropDownStyle == ComboBoxStyle.DropDownList) return String.Empty; else{ int start, end; if ( (Widget as Gtk.Combo).Entry.GetSelectionBounds(out start, out end)) return (Widget as Gtk.Combo).Entry.GetChars (start, end); else return String.Empty; } } set{(Widget as Gtk.Combo).Entry.InsertText (value);} } [MonoTODO] public int SelectionLength { get{ return this.SelectedText.Length; } set{ if (value < 0) throw new ArgumentException ("SelectionLength"); if ((SelectionStart + value) > Text.Length){ value = Text.Length - SelectionStart; } (Widget as Gtk.Combo).Entry.SelectRegion ( SelectionStart, SelectionStart + value); } } [MonoTODO] public int SelectionStart { get{ int start, end; if ( (Widget as Gtk.Combo).Entry.GetSelectionBounds(out start, out end)) return start; else return (Widget as Gtk.Combo).Entry.Position; } set{ if (value < 0) throw new ArgumentException ("SelectionStart"); if (value > this.Text.Length) value = this.Text.Length; int length = SelectionLength; if ((value + length) > Text.Length) length = Text.Length - value; (Widget as Gtk.Combo).Entry.SelectRegion (value, length); } } [MonoTODO] public bool Sorted { get{return sorted;} set{ if (! sorted && value ) Items.Sort(); sorted = value; } } [MonoTODO] public override string Text{ get{ return (Widget as Gtk.Combo).Entry.Text; } set{ disableChanging = true; if ((value == null) || (value == String.Empty)) this.SelectedIndex = -1; else (Widget as Gtk.Combo).Entry.Text = value; disableChanging = false; } } [MonoTODO] protected virtual void AddItemsCore( object[] value){ } [MonoTODO] public void BeginUpdate () { updating = true; } [MonoTODO] protected override void Dispose( bool disposing){ base.Dispose(disposing); } [MonoTODO] public void EndUpdate () { updating = false; Update(); } [MonoTODO] public int FindString (string value){ return alist.IndexOf(value); } [MonoTODO] public int FindString(string s, int startIndex){ throw new NotImplementedException(); } [MonoTODO] public int FindStringExact( string s){ throw new NotImplementedException(); } [MonoTODO] public int FindStringExact( string s, int startIndex){ throw new NotImplementedException(); } [MonoTODO] public int GetItemHeight(int index){ throw new NotImplementedException(); } protected virtual void OnDrawItem(DrawItemEventArgs e){ if (DrawItem != null) DrawItem (this,e); } protected virtual void OnDropDown( EventArgs e){ if (DropDown != null) DropDown (this, e); } protected virtual void OnDropDownStyleChanged( EventArgs e){ if (DropDownStyleChanged != null) DropDownStyleChanged (this, e); } protected virtual void OnMeasureItem(MeasureItemEventArgs e){ if (MeasureItem != null) MeasureItem (this, e); } protected override void OnSelectedIndexChanged(EventArgs e){ base.OnSelectedIndexChanged(e); if (SelectedIndexChanged != null) SelectedIndexChanged (this, e); } // Don't use [MonoTODO] protected virtual void OnSelectedItemChanged(EventArgs e){ } protected override void OnSelectedValueChanged (EventArgs e){ base.OnSelectedValueChanged (e); } protected virtual void OnSelectionChangeCommitted( EventArgs e){ if (SelectionChangeCommitted != null) SelectionChangeCommitted (this, e); } [MonoTODO] protected override void RefreshItem(int index){ } [MonoTODO] public void Select(int start, int length){ } [MonoTODO] public void SelectAll(){ } [MonoTODO] protected override void SetItemCore( int index, object value){ } [MonoTODO] protected override void SetItemsCore( IList value){ } public override string ToString(){ return "System.Windows.Forms.ComboBox, Items.Count: " + Items.Count; } // ? [MonoTODO] public override void Update () { disableChanging = true; String tmp = (Widget as Gtk.Combo).Entry.Text; String[] strings = new String [this.Items.Count]; int i=0; foreach (String s in Items){ strings[i++] = s; } if (strings.Length > 0) (Widget as Gtk.Combo).SetPopdownStrings(strings); else (Widget as Gtk.Combo).SetPopdownStrings(""); (Widget as Gtk.Combo).Entry.Text = tmp; disableChanging = false; } public event DrawItemEventHandler DrawItem; public event EventHandler DropDown; public event EventHandler DropDownStyleChanged; public event MeasureItemEventHandler MeasureItem; public event EventHandler SelectedIndexChanged; public event EventHandler SelectionChangeCommitted; internal override Gtk.Widget CreateWidget () { Gtk.Combo com1 = new Gtk.Combo(); com1.SetPopdownStrings(""); com1.DisableActivate(); com1.Entry.Changed += new EventHandler (OnEntryChanged); return com1; } internal void OnEntryChanged (object o, EventArgs args){ if (disableChanging) return; if (this.SelectedIndex != -1){ OnSelectionChangeCommitted (EventArgs.Empty); OnSelectedIndexChanged (EventArgs.Empty); } } /// sub-class: ComboBox.ObjectCollection /// /// Represents the collection of items in a ComboBox. /// [MonoTODO] public class ObjectCollection : IList, ICollection, IEnumerable { private ArrayList collection_ = new ArrayList (); private ComboBox owner_ = null; /// --- ObjectCollection.constructor --- public ObjectCollection (ComboBox owner) { owner_ = owner; } /// --- ObjectCollection Properties --- public int Count { get { return collection_.Count; } } public bool IsReadOnly { get { return collection_.IsReadOnly; } } [MonoTODO] object IList.this[int index] { get { return collection_[index]; } set { collection_[index] = value; if (!owner_.updating) owner_.Update(); } } [MonoTODO] public object this[int index] { get { return collection_[index]; } set { collection_[index] = value; if (!owner_.updating) owner_.Update(); } } /// --- ICollection properties --- bool IList.IsFixedSize { get { return collection_.IsFixedSize; } } object ICollection.SyncRoot { get { return collection_.SyncRoot; } } bool ICollection.IsSynchronized { get { return collection_.IsSynchronized; } } /// --- methods --- /// --- ObjectCollection Methods --- /// Note: IList methods are stubbed out, otherwise IList interface cannot be implemented [MonoTODO] public int Add(object item) { int idx=0; if ( owner_.Sorted){ idx = collection_.BinarySearch(item, ComboBoxComparer.Instance); if (idx < 0) idx = ~idx; collection_.Insert (idx, item); } else { idx = collection_.Add (item); } if (!owner_.updating) owner_.Update(); return idx; } [MonoTODO] public void AddRange(object[] items){ owner_.BeginUpdate(); foreach(object item in items) { Add(item); } owner_.EndUpdate(); } [MonoTODO] public void Clear(){ collection_.Clear(); owner_.Update(); } public bool Contains(object value){ return collection_.Contains(value); } public void CopyTo(object[] dest,int arrayIndex){ collection_.CopyTo(dest, arrayIndex); } /// for ICollection: void ICollection.CopyTo(Array dest,int index){ collection_.CopyTo(dest, index); } public IEnumerator GetEnumerator(){ return collection_.GetEnumerator(); } public int IndexOf(object value){ return collection_.IndexOf(value); } [MonoTODO] public void Insert(int index,object item){ collection_.Insert (index, item); if (! owner_.updating) owner_.Update(); } public void Remove(object value){ collection_.Remove(value); if (! owner_.updating) owner_.Update(); } [MonoTODO] public void RemoveAt(int index){ collection_.RemoveAt (index); if (!owner_.updating) owner_.Update(); } internal void Sort(){ collection_.Sort(ComboBoxComparer.Instance); owner_.Update(); } } // --- end of ComboBox.ObjectCollection --- internal class ComboBoxComparer : System.Collections.IComparer { private static ComboBoxComparer instance = null; private ComboBoxComparer(){ } public static ComboBoxComparer Instance{ get{ if (instance == null) instance = new ComboBoxComparer(); return instance; } } public int Compare (object x, object y){ string s1 = (x as string).ToUpper(); string s2 = (y as string).ToUpper(); return Comparer.Default.Compare (s1, s2); } } } }