// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-// Copyright (c) 2004-2005 Novell, Inc.
+// Copyright (c) 2004-2006 Novell, Inc.
//
// Authors:
// Jordi Mas i Hernandez, jordi@ximian.com
+// Mike Kestner <mkestner@novell.com>
//
//
{
private CheckedIndexCollection checked_indices;
private CheckedItemCollection checked_items;
- private bool check_onclick;
- private bool three_dcheckboxes;
+ private Hashtable check_states = new Hashtable ();
+ private bool check_onclick = false;
+ private bool three_dcheckboxes = false;
public CheckedListBox ()
{
- items = new CheckedListBox.ObjectCollection (this);
checked_indices = new CheckedIndexCollection (this);
checked_items = new CheckedItemCollection (this);
- check_onclick = false;
- three_dcheckboxes = false;
- listbox_info.item_height = FontHeight + 2;
+ SetStyle (ControlStyles.ResizeRedraw, true);
}
#region events
+ static object ItemCheckEvent = new object ();
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler Click;
+ public new event EventHandler Click {
+ add { base.Click += value; }
+ remove { base.Click -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler DataSourceChanged;
+ public new event EventHandler DataSourceChanged {
+ add { base.DataSourceChanged += value; }
+ remove { base.DataSourceChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler DisplayMemberChanged;
+ public new event EventHandler DisplayMemberChanged {
+ add { base.DisplayMemberChanged += value; }
+ remove { base.DisplayMemberChanged -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event DrawItemEventHandler DrawItem;
- public event ItemCheckEventHandler ItemCheck;
-
+ public new event DrawItemEventHandler DrawItem {
+ add { base.DrawItem += value; }
+ remove { base.DrawItem -= value; }
+ }
+
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event MeasureItemEventHandler MeasureItem;
+ public new event MeasureItemEventHandler MeasureItem {
+ add { base.MeasureItem += value; }
+ remove { base.MeasureItem -= value; }
+ }
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
- public new event EventHandler ValueMemberChanged;
+ public new event EventHandler ValueMemberChanged {
+ add { base.ValueMemberChanged += value; }
+ remove { base.ValueMemberChanged -= value; }
+ }
+
+ public event ItemCheckEventHandler ItemCheck {
+ add { Events.AddHandler (ItemCheckEvent, value); }
+ remove { Events.RemoveHandler (ItemCheckEvent, value); }
+ }
#endregion Events
#region Public Properties
[Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]\r
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public CheckedListBox.CheckedIndexCollection CheckedIndices {
get {return checked_indices; }
}
[Browsable (false)]
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]\r
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public CheckedListBox.CheckedItemCollection CheckedItems {
get {return checked_items; }
}
}
[EditorBrowsable (EditorBrowsableState.Never)]
- [Browsable (false)]\r
+ [Browsable (false)]
public new object DataSource {
get { return base.DataSource; }
+ // FIXME: docs say you can't use a DataSource with this subclass
set { base.DataSource = value; }
}
[EditorBrowsable (EditorBrowsableState.Never)]
public override DrawMode DrawMode {
get { return DrawMode.Normal; }
- set { /* Not possible */ }
+ set { /* Not an exception, but has no effect. */ }
}
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[EditorBrowsable (EditorBrowsableState.Never)]
public override int ItemHeight {
- get { return listbox_info.item_height; }
- set { /* Not possible */ }
+ get { return base.ItemHeight; }
+ set { /* Not an exception, but has no effect. */ }
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
public override SelectionMode SelectionMode {
get { return base.SelectionMode; }
set {
+ if (!Enum.IsDefined (typeof (SelectionMode), value))
+ throw new InvalidEnumArgumentException ("value", (int) value, typeof (SelectionMode));
+
if (value == SelectionMode.MultiSimple || value == SelectionMode.MultiExtended)
- throw new InvalidEnumArgumentException ("Multi selection modes not supported");
+ throw new ArgumentException ("Multi selection not supported on CheckedListBox");
base.SelectionMode = value;
}
{
return base.CreateAccessibilityInstance ();
}
- \r
+
protected override ListBox.ObjectCollection CreateItemCollection ()
{
return new ObjectCollection (this);
public bool GetItemChecked (int index)
{
- return (GetItemCheckState (index) == CheckState.Checked);
+ return check_states.Contains (Items [index]);
}
- \r
+
public CheckState GetItemCheckState (int index)
{
if (index < 0 || index >= Items.Count)
throw new ArgumentOutOfRangeException ("Index of out range");
- return (Items.GetListBoxItem (index)).State;
+ object o = Items [index];
+ if (check_states.Contains (o))
+ return (CheckState) check_states [o];
+ else
+ return CheckState.Unchecked;
}
protected override void OnBackColorChanged (EventArgs e)
protected override void OnClick (EventArgs e)
{
base.OnClick (e);
-
- if (check_onclick) {
- if (focused_item != -1) {
- SetItemChecked (focused_item, !GetItemChecked (focused_item));
- }
- }
-
- if (Click != null)
- Click (this, EventArgs.Empty);
}
- \r
+
protected override void OnDrawItem (DrawItemEventArgs e)
{
+ if (check_states.Contains (Items [e.Index])) {
+ DrawItemState state = e.State | DrawItemState.Checked;
+ if (((CheckState) check_states [Items [e.Index]]) == CheckState.Indeterminate)
+ state |= DrawItemState.Inactive;
+ e = new DrawItemEventArgs (e.Graphics, e.Font, e.Bounds, e.Index, state, e.ForeColor, e.BackColor);
+ }
ThemeEngine.Current.DrawCheckedListBoxItem (this, e);
}
protected virtual void OnItemCheck (ItemCheckEventArgs ice)
{
- if (ItemCheck != null)
- ItemCheck (this, ice);
+ ItemCheckEventHandler eh = (ItemCheckEventHandler)(Events [ItemCheckEvent]);
+ if (eh != null)
+ eh (this, ice);
}
protected override void OnKeyPress (KeyPressEventArgs e)
{
base.OnKeyPress (e);
- if (e.KeyChar == ' ') { // Space should check focused item
- if (focused_item != -1) {
- SetItemChecked (focused_item, !GetItemChecked (focused_item));
- }
- }
+ if (e.KeyChar == ' ' && FocusedItem != -1)
+ SetItemChecked (FocusedItem, !GetItemChecked (FocusedItem));
}
protected override void OnMeasureItem (MeasureItemEventArgs e)
{
- if (MeasureItem != null)
- MeasureItem (this, e);
+ base.OnMeasureItem (e);
}
protected override void OnSelectedIndexChanged (EventArgs e)
if (!Enum.IsDefined (typeof (CheckState), value))
throw new InvalidEnumArgumentException (string.Format("Enum argument value '{0}' is not valid for CheckState", value));
- CheckState old_value = (Items.GetListBoxItem (index)).State;
+ CheckState old_value = GetItemCheckState (index);
if (old_value == value)
return;
- (Items.GetListBoxItem (index)).State = value;
-
- Rectangle invalidate = GetItemDisplayRectangle (index, LBoxInfo.top_item);
+ OnItemCheck (new ItemCheckEventArgs (index, value, old_value));
switch (value) {
- case CheckState.Checked:
- checked_indices.AddIndex (index);
- checked_items.AddObject (Items[index]);
- break;
- case CheckState.Unchecked:
- checked_indices.RemoveIndex (index);
- checked_items.RemoveObject (Items[index]);
- break;
- case CheckState.Indeterminate:
- default:
- break;
+ case CheckState.Checked:
+ case CheckState.Indeterminate:
+ check_states [Items[index]] = value;
+ break;
+ case CheckState.Unchecked:
+ check_states.Remove (Items[index]);
+ break;
+ default:
+ break;
}
- OnItemCheck (new ItemCheckEventArgs (index, value, old_value));
+ UpdateCollections ();
- if (ClientRectangle.Contains (invalidate))
- Invalidate (invalidate);
+ InvalidateCheckbox (index);
}
protected override void WmReflectCommand (ref Message m)
#region Private Methods
- internal override void OnMouseDownLB (object sender, MouseEventArgs e)
- {
- base.OnMouseDownLB (sender, e);
-
- Rectangle hit_rect, item_rect;
- CheckState value = CheckState.Checked;
- bool set_value = false;
- int index = IndexFromPointDisplayRectangle (e.X, e.Y);
+ int last_clicked_index = -1;
- if (index == -1)
- return;
-
- /* CheckBox hit */
- hit_rect = item_rect = GetItemDisplayRectangle (index, LBoxInfo.top_item); // Full item rect
- hit_rect.X += ThemeEngine.Current.CheckedListBoxCheckRectangle().X;
- hit_rect.Y += ThemeEngine.Current.CheckedListBoxCheckRectangle().Y;
- hit_rect.Width = ThemeEngine.Current.CheckedListBoxCheckRectangle().Width;
- hit_rect.Height = ThemeEngine.Current.CheckedListBoxCheckRectangle().Height;
-
- if ((Items.GetListBoxItem (index)).State == CheckState.Checked)
- value = CheckState.Unchecked;
-
- if (hit_rect.Contains (e.X, e.Y) == true) {
- set_value = true;
-
- } else {
- if (item_rect.Contains (e.X, e.Y) == true) {
- if (!check_onclick) {
- if ((Items.GetListBoxItem (index)).Selected == true)
- set_value = true;
- }
- }
+ internal override void OnItemClick (int index)
+ {
+ if (CheckOnClick || last_clicked_index == index) {
+ if (GetItemChecked (index))
+ SetItemCheckState (index, CheckState.Unchecked);
+ else
+ SetItemCheckState (index, CheckState.Checked);
}
-
- if (set_value)
- SetItemCheckState (index, value);
+ last_clicked_index = index;
+ base.OnItemClick (index);
}
- internal override void UpdateItemInfo (UpdateOperation operation, int first, int last)
+ internal override void CollectionChanged ()
{
- base.UpdateItemInfo (operation, first, last);
- CheckedItems.ReCreate ();
- CheckedIndices.ReCreate ();
+ base.CollectionChanged ();
+ UpdateCollections ();
+ }
+
+ private void InvalidateCheckbox (int index)
+ {
+ Rectangle area = GetItemDisplayRectangle (index, TopIndex);
+ area.X += 2;
+ area.Y += (area.Height - 11) / 2;
+ area.Width = 11;
+ area.Height = 11;
+ Invalidate (area);
+ }
+
+ private void UpdateCollections ()
+ {
+ CheckedItems.Refresh ();
+ CheckedIndices.Refresh ();
}
#endregion Private Methods
- public class ObjectCollection : ListBox.ObjectCollection
+ public new class ObjectCollection : ListBox.ObjectCollection
{
+ private CheckedListBox owner;
+
public ObjectCollection (CheckedListBox owner) : base (owner)
{
-
+ this.owner = owner;
}
- public int Add (object item, bool isChecked)
+ public int Add (object item, bool isChecked)
{
- if (isChecked)
- return Add (item, CheckState.Checked);
-
- return Add (item, CheckState.Unchecked);
-
+ return Add (item, isChecked ? CheckState.Checked : CheckState.Unchecked);
}
- \r
+
public int Add (object item, CheckState check)
{
- int cnt = object_items.Count;
- ListBox.ListBoxItem box_item = new ListBox.ListBoxItem (cnt);
- box_item.State = check;
- object_items.Add (item);
- listbox_items.Add (box_item);
- return cnt;
+ Add (item);
+ if (check != CheckState.Unchecked)
+ owner.check_states [item] = check;
+ if (check == CheckState.Checked)
+ owner.OnItemCheck (new ItemCheckEventArgs (Count-1, check, CheckState.Unchecked));
+ owner.UpdateCollections ();
+ return Count - 1;
}
}
- /*
- CheckedListBox.CheckedIndexCollection
- */
public class CheckedIndexCollection : IList, ICollection, IEnumerable
{
private CheckedListBox owner;
}
#region Public Properties
- public virtual int Count {
+ public int Count {
get { return indices.Count; }
}
- public virtual bool IsReadOnly {
+ public bool IsReadOnly {
get { return true;}
}
}
- public virtual void CopyTo (Array dest, int index)
+ public void CopyTo (Array dest, int index)
{
indices.CopyTo (dest, index);
}
- public virtual IEnumerator GetEnumerator ()
+ public IEnumerator GetEnumerator ()
{
return indices.GetEnumerator ();
}
}
#region Private Methods
-
- internal void AddIndex (int index)
- {
- indices.Add (index);
- }
-
- internal void ClearIndices ()
+ internal void Refresh ()
{
indices.Clear ();
+ for (int i = 0; i < owner.Items.Count; i++)
+ if (owner.check_states.Contains (owner.Items [i]))
+ indices.Add (i);
}
-
- internal void RemoveIndex (int index)
- {
- indices.Remove (index);
- }
-
- internal void ReCreate ()
- {
- indices.Clear ();
-
- for (int i = 0; i < owner.Items.Count; i++) {
- ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
-
- if (item.State == CheckState.Checked)
- indices.Add (item.Index);
- }
- }
-
#endregion Private Methods
+
}
- /*
- CheckedItemCollection
- */
public class CheckedItemCollection : IList, ICollection, IEnumerable
{
private CheckedListBox owner;
- private ArrayList object_items = new ArrayList ();
+ private ArrayList list = new ArrayList ();
internal CheckedItemCollection (CheckedListBox owner)
{
}
#region Public Properties
- public virtual int Count {
- get { return object_items.Count; }
+ public int Count {
+ get { return list.Count; }
}
- public virtual bool IsReadOnly {
+ public bool IsReadOnly {
get { return true; }
}
[Browsable (false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public virtual object this [int index] {
+ public object this [int index] {
get {
if (index < 0 || index >= Count)
throw new ArgumentOutOfRangeException ("Index of out range");
- return object_items[index];
+ return list[index];
}
set {throw new NotSupportedException ();}
}
get { return true; }
}
- object IList.this[int index] {
- get { return object_items[index]; }
- set { throw new NotSupportedException (); }
- }
-
#endregion Public Properties
#region Public Methods
- public virtual bool Contains (object selectedObject)
+ public bool Contains (object selectedObject)
{
- return object_items.Contains (selectedObject);
+ return list.Contains (selectedObject);
}
- public virtual void CopyTo (Array dest, int index)
+ public void CopyTo (Array dest, int index)
{
- object_items.CopyTo (dest, index);
+ list.CopyTo (dest, index);
}
int IList.Add (object value)
throw new NotSupportedException ();
}
- bool IList.Contains (object selectedIndex)
- {
- throw new NotImplementedException ();
- }
- \r
void IList.Insert (int index, object value)
{
throw new NotSupportedException ();
{
throw new NotSupportedException ();
}
- \r
+
public int IndexOf (object item)
{
- return object_items.IndexOf (item);
+ return list.IndexOf (item);
}
- public virtual IEnumerator GetEnumerator ()
+ public IEnumerator GetEnumerator ()
{
- return object_items.GetEnumerator ();
+ return list.GetEnumerator ();
}
#endregion Public Methods
#region Private Methods
- internal void AddObject (object obj)
+ internal void Refresh ()
{
- object_items.Add (obj);
+ list.Clear ();
+ for (int i = 0; i < owner.Items.Count; i++)
+ if (owner.check_states.Contains (owner.Items [i]))
+ list.Add (owner.Items[i]);
}
+ #endregion Private Methods
+ }
+#if NET_2_0
- internal void ClearObjects ()
- {
- object_items.Clear ();
- }
-
- internal void ReCreate ()
- {
- object_items.Clear ();
-
- for (int i = 0; i < owner.Items.Count; i++) {
- ListBox.ListBoxItem item = owner.Items.GetListBoxItem (i);
-
- if (item.State == CheckState.Checked)
- object_items.Add (owner.Items[item.Index]);
- }
+ public bool UseCompatibleTextRendering {
+ get {
+ return use_compatible_text_rendering;
}
- internal void RemoveObject (object obj)
- {
- object_items.Remove (obj);
+ set {
+ use_compatible_text_rendering = value;
}
- #endregion Private Methods
}
+#endif
+
}
}