1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2004-2005 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Reflection;
35 namespace System.Windows.Forms
38 public class CheckedListBox : ListBox
40 private CheckedIndexCollection checked_indices;
41 private CheckedItemCollection checked_items;
42 private bool check_onclick;
43 private bool three_dcheckboxes;
45 public CheckedListBox ()
47 items = new CheckedListBox.ObjectCollection (this);
48 checked_indices = new CheckedIndexCollection (this);
49 checked_items = new CheckedItemCollection (this);
50 check_onclick = false;
51 three_dcheckboxes = false;
52 listbox_info.item_height = FontHeight + 2;
57 [EditorBrowsable (EditorBrowsableState.Never)]
58 public new event EventHandler Click;
61 [EditorBrowsable (EditorBrowsableState.Never)]
62 public new event EventHandler DataSourceChanged;
65 [EditorBrowsable (EditorBrowsableState.Never)]
66 public new event EventHandler DisplayMemberChanged;
69 [EditorBrowsable (EditorBrowsableState.Never)]
70 public new event DrawItemEventHandler DrawItem;
71 public event ItemCheckEventHandler ItemCheck;
74 [EditorBrowsable (EditorBrowsableState.Never)]
75 public new event MeasureItemEventHandler MeasureItem;
78 [EditorBrowsable (EditorBrowsableState.Never)]
79 public new event EventHandler ValueMemberChanged;
82 #region Public Properties
85 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
86 public CheckedListBox.CheckedIndexCollection CheckedIndices {
87 get {return checked_indices; }
91 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
92 public CheckedListBox.CheckedItemCollection CheckedItems {
93 get {return checked_items; }
96 [DefaultValue (false)]
97 public bool CheckOnClick {
98 get { return check_onclick; }
99 set { check_onclick = value; }
102 protected override CreateParams CreateParams {
103 get { return base.CreateParams;}
106 [EditorBrowsable (EditorBrowsableState.Never)]
108 public new object DataSource {
109 get { return base.DataSource; }
110 set { base.DataSource = value; }
113 [EditorBrowsable (EditorBrowsableState.Never)]
115 public new string DisplayMember {
116 get { return base.DisplayMember; }
117 set { base.DisplayMember = value; }
121 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
122 [EditorBrowsable (EditorBrowsableState.Never)]
123 public override DrawMode DrawMode {
124 get { return DrawMode.Normal; }
125 set { /* Not possible */ }
129 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
130 [EditorBrowsable (EditorBrowsableState.Never)]
131 public override int ItemHeight {
132 get { return listbox_info.item_height; }
133 set { /* Not possible */ }
136 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
138 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
139 public new CheckedListBox.ObjectCollection Items {
140 get { return (CheckedListBox.ObjectCollection) base.Items; }
143 public override SelectionMode SelectionMode {
144 get { return base.SelectionMode; }
146 if (value == SelectionMode.MultiSimple || value == SelectionMode.MultiExtended)
147 throw new InvalidEnumArgumentException ("Multi selection modes not supported");
149 base.SelectionMode = value;
153 [DefaultValue (false)]
154 public bool ThreeDCheckBoxes {
155 get { return three_dcheckboxes; }
157 if (three_dcheckboxes == value)
160 three_dcheckboxes = value;
166 [EditorBrowsable (EditorBrowsableState.Never)]
167 public new string ValueMember {
168 get { return base.ValueMember; }
169 set { base.ValueMember = value; }
172 #endregion Public Properties
174 #region Public Methods
176 protected override AccessibleObject CreateAccessibilityInstance ()
178 return base.CreateAccessibilityInstance ();
181 protected override ListBox.ObjectCollection CreateItemCollection ()
183 return new ObjectCollection (this);
186 public bool GetItemChecked (int index)
188 return (GetItemCheckState (index) != CheckState.Unchecked);
191 public CheckState GetItemCheckState (int index)
193 if (index < 0 || index >= Items.Count)
194 throw new ArgumentOutOfRangeException ("Index of out range");
196 return (Items.GetListBoxItem (index)).State;
199 protected override void OnBackColorChanged (EventArgs e)
201 base.OnBackColorChanged (e);
204 protected override void OnClick (EventArgs e)
209 Click (this, EventArgs.Empty);
212 protected override void OnDrawItem (DrawItemEventArgs e)
214 ThemeEngine.Current.DrawCheckedListBoxItem (this, e);
217 protected override void OnFontChanged (EventArgs e)
219 base.OnFontChanged (e);
222 protected override void OnHandleCreated (EventArgs e)
224 base.OnHandleCreated (e);
227 protected virtual void OnItemCheck (ItemCheckEventArgs ice)
229 if (ItemCheck != null)
230 ItemCheck (this, ice);
233 protected override void OnKeyPress (KeyPressEventArgs e)
237 if (e.KeyChar == ' ') { // Space should check focused item
238 if (focused_item != -1) {
239 SetItemChecked (focused_item, !GetItemChecked (focused_item));
244 protected override void OnMeasureItem (MeasureItemEventArgs e)
246 if (MeasureItem != null)
247 MeasureItem (this, e);
250 protected override void OnSelectedIndexChanged (EventArgs e)
252 base.OnSelectedIndexChanged (e);
255 public void SetItemChecked (int index, bool value)
257 SetItemCheckState (index, value ? CheckState.Checked : CheckState.Unchecked);
260 public void SetItemCheckState (int index, CheckState value)
262 if (index < 0 || index >= Items.Count)
263 throw new ArgumentOutOfRangeException ("Index of out range");
265 if (!Enum.IsDefined (typeof (CheckState), value))
266 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for CheckState", value));
268 CheckState old_value = (Items.GetListBoxItem (index)).State;
270 if (old_value == value)
273 (Items.GetListBoxItem (index)).State = value;
275 Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
278 case CheckState.Checked:
279 checked_indices.AddIndex (index);
280 checked_items.AddObject (Items[index]);
282 case CheckState.Unchecked:
283 checked_indices.RemoveIndex (index);
284 checked_items.RemoveObject (Items[index]);
286 case CheckState.Indeterminate:
291 OnItemCheck (new ItemCheckEventArgs (index, value, old_value));
293 if (ClientRectangle.Contains (invalidate))
294 Invalidate (invalidate);
297 protected override void WmReflectCommand (ref Message m)
299 base.WmReflectCommand (ref m);
302 protected override void WndProc (ref Message m)
304 base.WndProc (ref m);
307 #endregion Public Methods
309 #region Private Methods
311 internal override void OnMouseDownLB (object sender, MouseEventArgs e)
313 Rectangle hit_rect, item_rect;
314 CheckState value = CheckState.Checked;
315 bool set_value = false;
316 int index = IndexFromPointDisplayRectangle (e.X, e.Y);
319 if (e.Button == MouseButtons.Left) {
328 hit_rect = item_rect = GetItemDisplayRectangle (index, LBoxInfo.top_item); // Full item rect
329 hit_rect.X += ThemeEngine.Current.CheckedListBoxCheckRectangle().X;
330 hit_rect.Y += ThemeEngine.Current.CheckedListBoxCheckRectangle().Y;
331 hit_rect.Width = ThemeEngine.Current.CheckedListBoxCheckRectangle().Width;
332 hit_rect.Height = ThemeEngine.Current.CheckedListBoxCheckRectangle().Height;
334 if ((Items.GetListBoxItem (index)).State == CheckState.Checked) { //From checked to unchecked
335 value = CheckState.Unchecked;
342 if ((Items.GetListBoxItem (index)).Selected == true)
348 SetItemCheckState (index, value);
350 SelectedItemFromNavigation (index);
351 SetFocusedItem (index);
354 internal override void UpdateItemInfo (UpdateOperation operation, int first, int last)
356 base.UpdateItemInfo (operation, first, last);
357 CheckedItems.ReCreate ();
358 CheckedIndices.ReCreate ();
361 #endregion Private Methods
363 public class ObjectCollection : ListBox.ObjectCollection
365 private CheckedListBox owner;
367 public ObjectCollection (CheckedListBox owner) : base (owner)
372 public int Add (object item, bool isChecked)
375 return Add (item, CheckState.Checked);
377 return Add (item, CheckState.Unchecked);
381 public int Add (object item, CheckState check)
383 int cnt = object_items.Count;
384 ListBox.ListBoxItem box_item = new ListBox.ListBoxItem (cnt);
385 box_item.State = check;
386 object_items.Add (item);
387 listbox_items.Add (box_item);
388 if (check == CheckState.Checked)
389 owner.OnItemCheck (new ItemCheckEventArgs (cnt, check, CheckState.Unchecked));
390 owner.UpdateItemInfo (UpdateOperation.AddItems, cnt, cnt);
396 CheckedListBox.CheckedIndexCollection
398 public class CheckedIndexCollection : IList, ICollection, IEnumerable
400 private CheckedListBox owner;
401 private ArrayList indices = new ArrayList ();
403 internal CheckedIndexCollection (CheckedListBox owner)
408 #region Public Properties
409 public virtual int Count {
410 get { return indices.Count; }
413 public virtual bool IsReadOnly {
417 bool ICollection.IsSynchronized {
418 get { return false; }
421 bool IList.IsFixedSize{
425 object ICollection.SyncRoot {
430 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
431 public int this[int index] {
433 if (index < 0 || index >= Count)
434 throw new ArgumentOutOfRangeException ("Index of out range");
436 return (int) indices[index];
439 #endregion Public Properties
441 public bool Contains (int index)
443 return indices.Contains (index);
447 public virtual void CopyTo (Array dest, int index)
449 indices.CopyTo (dest, index);
452 public virtual IEnumerator GetEnumerator ()
454 return indices.GetEnumerator ();
457 int IList.Add (object value)
459 throw new NotSupportedException ();
464 throw new NotSupportedException ();
467 bool IList.Contains (object index)
469 return Contains ((int)index);
472 int IList.IndexOf (object index)
474 return IndexOf ((int) index);
477 void IList.Insert (int index, object value)
479 throw new NotSupportedException ();
482 void IList.Remove (object value)
484 throw new NotSupportedException ();
487 void IList.RemoveAt (int index)
489 throw new NotSupportedException ();
492 object IList.this[int index]{
493 get {return indices[index]; }
494 set {throw new NotImplementedException (); }
497 public int IndexOf (int index)
499 return indices.IndexOf (index);
502 #region Private Methods
504 internal void AddIndex (int index)
509 internal void ClearIndices ()
514 internal void RemoveIndex (int index)
516 indices.Remove (index);
519 internal void ReCreate ()
523 for (int i = 0; i < owner.Items.Count; i++) {
524 ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
526 if (item.State == CheckState.Checked)
527 indices.Add (item.Index);
531 #endregion Private Methods
535 CheckedItemCollection
537 public class CheckedItemCollection : IList, ICollection, IEnumerable
539 private CheckedListBox owner;
540 private ArrayList object_items = new ArrayList ();
542 internal CheckedItemCollection (CheckedListBox owner)
547 #region Public Properties
548 public virtual int Count {
549 get { return object_items.Count; }
552 public virtual bool IsReadOnly {
557 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
558 public virtual object this [int index] {
560 if (index < 0 || index >= Count)
561 throw new ArgumentOutOfRangeException ("Index of out range");
563 return object_items[index];
565 set {throw new NotSupportedException ();}
568 bool ICollection.IsSynchronized {
572 object ICollection.SyncRoot {
576 bool IList.IsFixedSize {
580 object IList.this[int index] {
581 get { return object_items[index]; }
582 set { throw new NotSupportedException (); }
585 #endregion Public Properties
587 #region Public Methods
588 public virtual bool Contains (object selectedObject)
590 return object_items.Contains (selectedObject);
593 public virtual void CopyTo (Array dest, int index)
595 object_items.CopyTo (dest, index);
598 int IList.Add (object value)
600 throw new NotSupportedException ();
605 throw new NotSupportedException ();
608 bool IList.Contains (object selectedIndex)
610 throw new NotImplementedException ();
613 void IList.Insert (int index, object value)
615 throw new NotSupportedException ();
618 void IList.Remove (object value)
620 throw new NotSupportedException ();
623 void IList.RemoveAt (int index)
625 throw new NotSupportedException ();
628 public int IndexOf (object item)
630 return object_items.IndexOf (item);
633 public virtual IEnumerator GetEnumerator ()
635 return object_items.GetEnumerator ();
638 #endregion Public Methods
640 #region Private Methods
641 internal void AddObject (object obj)
643 object_items.Add (obj);
646 internal void ClearObjects ()
648 object_items.Clear ();
651 internal void ReCreate ()
653 object_items.Clear ();
655 for (int i = 0; i < owner.Items.Count; i++) {
656 ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
658 if (item.State == CheckState.Checked)
659 object_items.Add (owner.Items[item.Index]);
663 internal void RemoveObject (object obj)
665 object_items.Remove (obj);
667 #endregion Private Methods