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-2006 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
24 // Mike Kestner <mkestner@novell.com>
32 using System.Collections;
33 using System.ComponentModel;
34 using System.Reflection;
36 namespace System.Windows.Forms
39 public class CheckedListBox : ListBox
41 private CheckedIndexCollection checked_indices;
42 private CheckedItemCollection checked_items;
43 private Hashtable check_states = new Hashtable ();
44 private bool check_onclick = false;
45 private bool three_dcheckboxes = false;
47 public CheckedListBox ()
49 checked_indices = new CheckedIndexCollection (this);
50 checked_items = new CheckedItemCollection (this);
51 SetStyle (ControlStyles.ResizeRedraw, true);
56 [EditorBrowsable (EditorBrowsableState.Never)]
57 public new event EventHandler Click {
58 add { base.Click += value; }
59 remove { base.Click -= value; }
63 [EditorBrowsable (EditorBrowsableState.Never)]
64 public new event EventHandler DataSourceChanged {
65 add { base.DataSourceChanged += value; }
66 remove { base.DataSourceChanged -= value; }
70 [EditorBrowsable (EditorBrowsableState.Never)]
71 public new event EventHandler DisplayMemberChanged {
72 add { base.DisplayMemberChanged += value; }
73 remove { base.DisplayMemberChanged -= value; }
77 [EditorBrowsable (EditorBrowsableState.Never)]
78 public new event DrawItemEventHandler DrawItem {
79 add { base.DrawItem += value; }
80 remove { base.DrawItem -= value; }
84 [EditorBrowsable (EditorBrowsableState.Never)]
85 public new event MeasureItemEventHandler MeasureItem {
86 add { base.MeasureItem += value; }
87 remove { base.MeasureItem -= value; }
91 [EditorBrowsable (EditorBrowsableState.Never)]
92 public new event EventHandler ValueMemberChanged {
93 add { base.ValueMemberChanged += value; }
94 remove { base.ValueMemberChanged -= value; }
97 public event ItemCheckEventHandler ItemCheck;
100 #region Public Properties
103 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
104 public CheckedListBox.CheckedIndexCollection CheckedIndices {
105 get {return checked_indices; }
109 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
110 public CheckedListBox.CheckedItemCollection CheckedItems {
111 get {return checked_items; }
114 [DefaultValue (false)]
115 public bool CheckOnClick {
116 get { return check_onclick; }
117 set { check_onclick = value; }
120 protected override CreateParams CreateParams {
121 get { return base.CreateParams;}
124 [EditorBrowsable (EditorBrowsableState.Never)]
126 public new object DataSource {
127 get { return base.DataSource; }
128 // FIXME: docs say you can't use a DataSource with this subclass
129 set { base.DataSource = value; }
132 [EditorBrowsable (EditorBrowsableState.Never)]
134 public new string DisplayMember {
135 get { return base.DisplayMember; }
136 set { base.DisplayMember = value; }
140 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
141 [EditorBrowsable (EditorBrowsableState.Never)]
142 public override DrawMode DrawMode {
143 get { return DrawMode.Normal; }
144 set { /* Not an exception, but has no effect. */ }
148 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
149 [EditorBrowsable (EditorBrowsableState.Never)]
150 public override int ItemHeight {
151 get { return base.ItemHeight; }
152 set { /* Not an exception, but has no effect. */ }
155 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
157 [Editor ("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
158 public new CheckedListBox.ObjectCollection Items {
159 get { return (CheckedListBox.ObjectCollection) base.Items; }
162 public override SelectionMode SelectionMode {
163 get { return base.SelectionMode; }
165 if (value == SelectionMode.MultiSimple || value == SelectionMode.MultiExtended)
166 throw new InvalidEnumArgumentException ("Multi selection modes not supported");
168 base.SelectionMode = value;
172 [DefaultValue (false)]
173 public bool ThreeDCheckBoxes {
174 get { return three_dcheckboxes; }
176 if (three_dcheckboxes == value)
179 three_dcheckboxes = value;
185 [EditorBrowsable (EditorBrowsableState.Never)]
186 public new string ValueMember {
187 get { return base.ValueMember; }
188 set { base.ValueMember = value; }
191 #endregion Public Properties
193 #region Public Methods
195 protected override AccessibleObject CreateAccessibilityInstance ()
197 return base.CreateAccessibilityInstance ();
200 protected override ListBox.ObjectCollection CreateItemCollection ()
202 return new ObjectCollection (this);
205 public bool GetItemChecked (int index)
207 return check_states.Contains (Items [index]);
210 public CheckState GetItemCheckState (int index)
212 if (index < 0 || index >= Items.Count)
213 throw new ArgumentOutOfRangeException ("Index of out range");
215 object o = Items [index];
216 if (check_states.Contains (o))
217 return (CheckState) check_states [o];
219 return CheckState.Unchecked;
222 protected override void OnBackColorChanged (EventArgs e)
224 base.OnBackColorChanged (e);
227 protected override void OnClick (EventArgs e)
232 protected override void OnDrawItem (DrawItemEventArgs e)
234 if (check_states.Contains (Items [e.Index])) {
235 DrawItemState state = e.State | DrawItemState.Checked;
236 if (((CheckState) check_states [Items [e.Index]]) == CheckState.Indeterminate)
237 state |= DrawItemState.Inactive;
238 e = new DrawItemEventArgs (e.Graphics, e.Font, e.Bounds, e.Index, state, e.ForeColor, e.BackColor);
240 ThemeEngine.Current.DrawCheckedListBoxItem (this, e);
243 protected override void OnFontChanged (EventArgs e)
245 base.OnFontChanged (e);
248 protected override void OnHandleCreated (EventArgs e)
250 base.OnHandleCreated (e);
253 protected virtual void OnItemCheck (ItemCheckEventArgs ice)
255 if (ItemCheck != null)
256 ItemCheck (this, ice);
259 protected override void OnKeyPress (KeyPressEventArgs e)
263 if (e.KeyChar == ' ' && FocusedItem != -1)
264 SetItemChecked (FocusedItem, !GetItemChecked (FocusedItem));
267 protected override void OnMeasureItem (MeasureItemEventArgs e)
269 base.OnMeasureItem (e);
272 protected override void OnSelectedIndexChanged (EventArgs e)
274 base.OnSelectedIndexChanged (e);
277 public void SetItemChecked (int index, bool value)
279 SetItemCheckState (index, value ? CheckState.Checked : CheckState.Unchecked);
282 public void SetItemCheckState (int index, CheckState value)
284 if (index < 0 || index >= Items.Count)
285 throw new ArgumentOutOfRangeException ("Index of out range");
287 if (!Enum.IsDefined (typeof (CheckState), value))
288 throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for CheckState", value));
290 CheckState old_value = GetItemCheckState (index);
292 if (old_value == value)
295 OnItemCheck (new ItemCheckEventArgs (index, value, old_value));
298 case CheckState.Checked:
299 case CheckState.Indeterminate:
300 check_states [Items[index]] = value;
302 case CheckState.Unchecked:
303 check_states.Remove (Items[index]);
309 UpdateCollections ();
311 InvalidateItem (index);
314 protected override void WmReflectCommand (ref Message m)
316 base.WmReflectCommand (ref m);
319 protected override void WndProc (ref Message m)
321 base.WndProc (ref m);
324 #endregion Public Methods
326 #region Private Methods
328 internal override void OnItemClick (int index)
330 if (GetItemChecked (index))
331 SetItemCheckState (index, CheckState.Unchecked);
332 else if (CheckOnClick || SelectedIndices.Contains (index))
333 SetItemCheckState (index, CheckState.Checked);
335 base.OnItemClick (index);
338 internal override void CollectionChanged ()
340 base.CollectionChanged ();
341 UpdateCollections ();
344 private void UpdateCollections ()
346 CheckedItems.Refresh ();
347 CheckedIndices.Refresh ();
350 #endregion Private Methods
352 public class ObjectCollection : ListBox.ObjectCollection
354 private CheckedListBox owner;
356 public ObjectCollection (CheckedListBox owner) : base (owner)
361 public int Add (object item, bool isChecked)
363 return Add (item, isChecked ? CheckState.Checked : CheckState.Unchecked);
366 public int Add (object item, CheckState check)
369 if (check != CheckState.Unchecked)
370 owner.check_states [item] = check;
371 if (check == CheckState.Checked)
372 owner.OnItemCheck (new ItemCheckEventArgs (Count, check, CheckState.Unchecked));
377 public class CheckedIndexCollection : IList, ICollection, IEnumerable
379 private CheckedListBox owner;
380 private ArrayList indices = new ArrayList ();
382 internal CheckedIndexCollection (CheckedListBox owner)
387 #region Public Properties
389 get { return indices.Count; }
392 public bool IsReadOnly {
396 bool ICollection.IsSynchronized {
397 get { return false; }
400 bool IList.IsFixedSize{
404 object ICollection.SyncRoot {
409 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
410 public int this[int index] {
412 if (index < 0 || index >= Count)
413 throw new ArgumentOutOfRangeException ("Index of out range");
415 return (int) indices[index];
418 #endregion Public Properties
420 public bool Contains (int index)
422 return indices.Contains (index);
426 public void CopyTo (Array dest, int index)
428 indices.CopyTo (dest, index);
431 public IEnumerator GetEnumerator ()
433 return indices.GetEnumerator ();
436 int IList.Add (object value)
438 throw new NotSupportedException ();
443 throw new NotSupportedException ();
446 bool IList.Contains (object index)
448 return Contains ((int)index);
451 int IList.IndexOf (object index)
453 return IndexOf ((int) index);
456 void IList.Insert (int index, object value)
458 throw new NotSupportedException ();
461 void IList.Remove (object value)
463 throw new NotSupportedException ();
466 void IList.RemoveAt (int index)
468 throw new NotSupportedException ();
471 object IList.this[int index]{
472 get {return indices[index]; }
473 set {throw new NotImplementedException (); }
476 public int IndexOf (int index)
478 return indices.IndexOf (index);
481 #region Private Methods
482 internal void Refresh ()
485 for (int i = 0; i < owner.Items.Count; i++)
486 if (owner.check_states.Contains (owner.Items [i]))
489 #endregion Private Methods
493 public class CheckedItemCollection : IList, ICollection, IEnumerable
495 private CheckedListBox owner;
496 private ArrayList list = new ArrayList ();
498 internal CheckedItemCollection (CheckedListBox owner)
503 #region Public Properties
505 get { return list.Count; }
508 public bool IsReadOnly {
513 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
514 public object this [int index] {
516 if (index < 0 || index >= Count)
517 throw new ArgumentOutOfRangeException ("Index of out range");
521 set {throw new NotSupportedException ();}
524 bool ICollection.IsSynchronized {
528 object ICollection.SyncRoot {
532 bool IList.IsFixedSize {
536 #endregion Public Properties
538 #region Public Methods
539 public bool Contains (object selectedObject)
541 return list.Contains (selectedObject);
544 public void CopyTo (Array dest, int index)
546 list.CopyTo (dest, index);
549 int IList.Add (object value)
551 throw new NotSupportedException ();
556 throw new NotSupportedException ();
559 void IList.Insert (int index, object value)
561 throw new NotSupportedException ();
564 void IList.Remove (object value)
566 throw new NotSupportedException ();
569 void IList.RemoveAt (int index)
571 throw new NotSupportedException ();
574 public int IndexOf (object item)
576 return list.IndexOf (item);
579 public IEnumerator GetEnumerator ()
581 return list.GetEnumerator ();
584 #endregion Public Methods
586 #region Private Methods
587 internal void Refresh ()
590 for (int i = 0; i < owner.Items.Count; i++)
591 if (owner.check_states.Contains (owner.Items [i]))
592 list.Add (owner.Items[i]);
594 #endregion Private Methods
598 public bool UseCompatibleTextRendering {
600 return use_compatible_text_rendering;
604 use_compatible_text_rendering = value;