Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / CheckedListBox.cs / 1 / CheckedListBox.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* */ namespace System.Windows.Forms { using Accessibility; using System.Text; using System.Runtime.Remoting; using System.Diagnostics; using System; using System.Security.Permissions; using System.Collections; using System.Windows.Forms; using System.Windows.Forms.VisualStyles; using System.Windows.Forms.ComponentModel; using System.Drawing; using System.ComponentModel; using System.Runtime.InteropServices; using Hashtable = System.Collections.Hashtable; using Microsoft.Win32; using System.Drawing.Design; using System.Globalization; using System.Drawing.Text; ////// /// [ ComVisible(true), ClassInterface(ClassInterfaceType.AutoDispatch), LookupBindingProperties(), // ...overrides equivalent attribute in ListControl SRDescription(SR.DescriptionCheckedListBox) ] public class CheckedListBox : ListBox { private int idealCheckSize = 13; private const int LB_CHECKED = 1; private const int LB_UNCHECKED = 0; private const int LB_ERROR = -1; ////// /// Displays a list with a checkbox to the left /// /// of each item. /// /// ////// /// Decides whether or not to ignore the next LBN_SELCHANGE /// message - used to prevent cursor keys from toggling checkboxes /// private bool killnextselect = false; ////// /// Current listener of the onItemCheck event. /// private ItemCheckEventHandler onItemCheck; ////// /// Indicates whether or not we should toggle check state on the first /// click on an item, or whether we should wait for the user to click /// again. /// private bool checkOnClick = false; ////// /// Should we use 3d checkboxes or flat ones? /// private bool flat = true; ////// /// Indicates which item was last selected. We want to keep track /// of this so we can be a little less aggressive about checking/ /// unchecking the items as the user moves around. /// private int lastSelected = -1; ////// /// The collection of checked items in the CheckedListBox. /// private CheckedItemCollection checkedItemCollection = null; private CheckedIndexCollection checkedIndexCollection = null; private static int LBC_GETCHECKSTATE; private static int LBC_SETCHECKSTATE; static CheckedListBox() { LBC_GETCHECKSTATE = SafeNativeMethods.RegisterWindowMessage("LBC_GETCHECKSTATE"); LBC_SETCHECKSTATE = SafeNativeMethods.RegisterWindowMessage("LBC_SETCHECKSTATE"); } ////// /// Creates a new CheckedListBox for the user. /// public CheckedListBox() : base() { // If we eat WM_ERASEBKGRND messages, the background will be // painted sometimes but not others. See ASURT 28545. // SetStyle(ControlStyles.Opaque, true); // If a long item is drawn with ellipsis, we must redraw the ellipsed part // as well as the newly uncovered region. SetStyle(ControlStyles.ResizeRedraw, true); } ////// /// Indicates whether or not the checkbox should be toggled whenever an /// item is selected. The default behaviour is to just change the /// selection, and then make the user click again to check it. However, /// some may prefer checking the item as soon as it is clicked. /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.CheckedListBoxCheckOnClickDescr) ] public bool CheckOnClick { get { return checkOnClick; } set { checkOnClick = value; } } ////// /// Collection of checked indices in this CheckedListBox. /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] public CheckedIndexCollection CheckedIndices { get { if (checkedIndexCollection == null) { checkedIndexCollection = new CheckedIndexCollection(this); } return checkedIndexCollection; } } ////// /// Collection of checked items in this CheckedListBox. /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] public CheckedItemCollection CheckedItems { get { if (checkedItemCollection == null) { checkedItemCollection = new CheckedItemCollection(this); } return checkedItemCollection; } } ////// /// This is called when creating a window. Inheriting classes can ovveride /// this to add extra functionality, but should not forget to first call /// base.CreateParams() to make sure the control continues to work /// correctly. /// protected override CreateParams CreateParams { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] get { CreateParams cp = base.CreateParams; cp.Style |= NativeMethods.LBS_OWNERDRAWFIXED | NativeMethods.LBS_WANTKEYBOARDINPUT; return cp; } } ////// /// CheckedListBox DataSource. /// ///[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new object DataSource { get { return base.DataSource; } set { base.DataSource = value; } } /// /// /// CheckedListBox DisplayMember. /// ///[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new string DisplayMember { get { return base.DisplayMember ; } set { base.DisplayMember = value; } } /// /// /// [ Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] public override DrawMode DrawMode { get { return DrawMode.Normal; } set { } } ///[To be supplied.] ////// /// [ Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ] public override int ItemHeight { get { // this should take FontHeight + buffer into Consideration. return Font.Height + 2; } set { } } ///[To be supplied.] ////// /// Collection of items in this listbox. /// [ SRCategory(SR.CatData), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Localizable(true), SRDescription(SR.ListBoxItemsDescr), Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)) ] new public CheckedListBox.ObjectCollection Items { get { return(CheckedListBox.ObjectCollection)base.Items; } } // Computes the maximum width of all items in the ListBox // internal override int MaxItemWidth { get { // Overridden to include the size of the checkbox // Allows for one pixel either side of the checkbox, plus another 1 pixel buffer = 3 pixels // return base.MaxItemWidth + idealCheckSize + 3; } } ////// /// For CheckedListBoxes, multi-selection is not supported. You can set /// selection to be able to select one item or no items. /// public override SelectionMode SelectionMode { get { return base.SelectionMode; } set { //valid values are 0x0 to 0x3 if (!ClientUtils.IsEnumValid(value, (int)value, (int)SelectionMode.None, (int)SelectionMode.MultiExtended)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(SelectionMode)); } if (value != SelectionMode.One && value != SelectionMode.None) { throw new ArgumentException(SR.GetString(SR.CheckedListBoxInvalidSelectionMode)); } if (value != SelectionMode) { base.SelectionMode = value; RecreateHandle(); } } } ////// /// Indicates if the CheckBoxes should show up as flat or 3D in appearance. /// [ SRCategory(SR.CatAppearance), DefaultValue(false), SRDescription(SR.CheckedListBoxThreeDCheckBoxesDescr) ] public bool ThreeDCheckBoxes { get { return !flat; } set { // change the style and repaint. // if (flat == value) { flat = !value; // see if we have some items, and only invalidate if we do. CheckedListBox.ObjectCollection items = (CheckedListBox.ObjectCollection) Items; if ((items != null) && (items.Count > 0)) { this.Invalidate(); } } } } ////// Determines whether to use compatible text rendering engine (GDI+) or not (GDI). /// [ DefaultValue(false), SRCategory(SR.CatBehavior), SRDescription(SR.UseCompatibleTextRenderingDescr) ] public bool UseCompatibleTextRendering { get{ return base.UseCompatibleTextRenderingInt; } set{ base.UseCompatibleTextRenderingInt = value; } } ////// Determines whether the control supports rendering text using GDI+ and GDI. /// This is provided for container controls to iterate through its children to set UseCompatibleTextRendering to the same /// value if the child control supports it. /// internal override bool SupportsUseCompatibleTextRendering { get { return true; } } ////// /// CheckedListBox ValueMember. /// ///[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new string ValueMember { get { return base.ValueMember; } set { base.ValueMember = value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler DataSourceChanged { add { base.DataSourceChanged += value; } remove { base.DataSourceChanged -= value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler DisplayMemberChanged { add { base.DisplayMemberChanged += value; } remove { base.DisplayMemberChanged -= value; } } /// /// /// [SRCategory(SR.CatBehavior), SRDescription(SR.CheckedListBoxItemCheckDescr)] public event ItemCheckEventHandler ItemCheck { add { onItemCheck += value; } remove { onItemCheck -= value; } } ///[To be supplied.] ////// [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] public new event EventHandler Click { add { base.Click += value; } remove { base.Click -= value; } } /// /// [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] public new event MouseEventHandler MouseClick { add { base.MouseClick += value; } remove { base.MouseClick -= value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event DrawItemEventHandler DrawItem { add { base.DrawItem += value; } remove { base.DrawItem -= value; } } /// /// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public new event MeasureItemEventHandler MeasureItem { add { base.MeasureItem += value; } remove { base.MeasureItem -= value; } } /// /// /// [ Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) ] public new Padding Padding { get { return base.Padding; } set { base.Padding = value;} } ////// ///[To be supplied.] ////// [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] new public event EventHandler ValueMemberChanged { add { base.ValueMemberChanged += value; } remove { base.ValueMemberChanged -= value; } } /// /// /// /// Constructs the new instance of the accessibility object for this control. Subclasses /// should not call base.CreateAccessibilityObject. /// protected override AccessibleObject CreateAccessibilityInstance() { return new CheckedListBoxAccessibleObject(this); } ////// /// protected override ListBox.ObjectCollection CreateItemCollection() { return new ObjectCollection(this); } ///[To be supplied.] ////// /// Gets the check value of the current item. This value will be from the /// System.Windows.Forms.CheckState enumeration. /// public CheckState GetItemCheckState(int index) { if (index < 0 || index >= Items.Count) throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture))); return CheckedItems.GetCheckedState(index); } ////// /// Indicates if the given item is, in any way, shape, or form, checked. /// This will return true if the item is fully or indeterminately checked. /// public bool GetItemChecked(int index) { return(GetItemCheckState(index) != CheckState.Unchecked); } ////// /// Invalidates the given item in the listbox /// ///private void InvalidateItem(int index) { if (IsHandleCreated) { NativeMethods.RECT rect = new NativeMethods.RECT(); SendMessage(NativeMethods.LB_GETITEMRECT, index, ref rect); SafeNativeMethods.InvalidateRect(new HandleRef(this, Handle), ref rect, false); } } /// /// /// A redirected LBN_SELCHANGE message notification. /// ///private void LbnSelChange() { // prepare to change the selection. we'll fire an event for // this. Note that we'll only change the selection when the // user clicks again on a currently selected item, or when the // user has CheckOnClick set to true. Otherwise // just using the up and down arrows selects or unselects // every item around town ... // // Get the index of the item to check/uncheck int index = SelectedIndex; // make sure we have a valid index, otherwise we're going to // fail ahead... if (index < 0 || index >= Items.Count) return; // Send an accessibility notification // AccessibilityNotifyClients(AccessibleEvents.Focus, index); AccessibilityNotifyClients(AccessibleEvents.Selection, index); //# VS7 86 if (!killnextselect && (index == lastSelected || checkOnClick == true)) { CheckState currentValue = CheckedItems.GetCheckedState(index); CheckState newValue = (currentValue != CheckState.Unchecked) ? CheckState.Unchecked : CheckState.Checked; ItemCheckEventArgs itemCheckEvent = new ItemCheckEventArgs(index, newValue, currentValue); OnItemCheck(itemCheckEvent); // take whatever value the user set, and set that as the value. // CheckedItems.SetCheckedState(index, itemCheckEvent.NewValue); } lastSelected = index; InvalidateItem(index); } /// /// /// Ensures that mouse clicks can toggle... /// ///protected override void OnClick(EventArgs e) { killnextselect = false; base.OnClick(e); } /// /// /// When the handle is created we can dump any cached item-check pairs. /// ///protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); SendMessage(NativeMethods.LB_SETITEMHEIGHT, 0, ItemHeight); } /// /// /// Actually goes and fires the drawItem event. Inheriting controls /// should use this to know when the event is fired [this is preferable to /// adding an event handler yourself for this event]. They should, /// however, remember to call base.OnDrawItem(e); to ensure the event is /// still fired to external listeners /// protected override void OnDrawItem(DrawItemEventArgs e) { object item; if (Font.Height < 0) { this.Font = Control.DefaultFont; } if (e.Index >= 0) { if (e.Index < Items.Count) { item = Items[e.Index]; } else { // If the item is not part of our collection, we will just // get the string for it and display it. // item = NativeGetItemText(e.Index); } Rectangle bounds = e.Bounds; int border = 1; int height = Font.Height + 2 * border; // set up the appearance of the checkbox // ButtonState state = ButtonState.Normal; if (flat) { state |= ButtonState.Flat; } if (e.Index < Items.Count) { switch (CheckedItems.GetCheckedState(e.Index)) { case CheckState.Checked: state |= ButtonState.Checked; break; case CheckState.Indeterminate: state |= ButtonState.Checked | ButtonState.Inactive; break; } } // If we are drawing themed CheckBox .. get the size from renderer.. // the Renderer might return a different size in different DPI modes.. if (Application.RenderWithVisualStyles) { VisualStyles.CheckBoxState cbState = CheckBoxRenderer.ConvertFromButtonState(state, false, ((e.State & DrawItemState.HotLight) == DrawItemState.HotLight)); idealCheckSize = (int)(CheckBoxRenderer.GetGlyphSize(e.Graphics, cbState)).Width; } // Determine bounds for the checkbox // int centeringFactor = Math.Max((height - idealCheckSize) / 2, 0); // Keep the checkbox within the item's upper and lower bounds if (centeringFactor + idealCheckSize > bounds.Height) { centeringFactor = bounds.Height - idealCheckSize; } Rectangle box = new Rectangle(bounds.X + border, bounds.Y + centeringFactor, idealCheckSize, idealCheckSize); if (RightToLeft == RightToLeft.Yes) { // For a RightToLeft checked list box, we want the checkbox // to be drawn at the right. // So we override the X position. box.X = bounds.X + bounds.Width - idealCheckSize - border; } // Draw the checkbox. // if (Application.RenderWithVisualStyles) { VisualStyles.CheckBoxState cbState = CheckBoxRenderer.ConvertFromButtonState(state, false, ((e.State & DrawItemState.HotLight) == DrawItemState.HotLight)); CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(box.X, box.Y), cbState); } else { ControlPaint.DrawCheckBox(e.Graphics, box, state); } // Determine bounds for the text portion of the item // Rectangle textBounds = new Rectangle( bounds.X + idealCheckSize + (border * 2), bounds.Y, bounds.Width - (idealCheckSize + (border * 2)) , bounds.Height); if (RightToLeft == RightToLeft.Yes) { // For a RightToLeft checked list box, we want the text // to be drawn at the left. // So we override the X position. textBounds.X = bounds.X; } // Setup text font, color, and text // string text = ""; Color backColor = (SelectionMode != SelectionMode.None) ? e.BackColor : BackColor; Color foreColor = (SelectionMode != SelectionMode.None) ? e.ForeColor : ForeColor; if (!Enabled) { foreColor = SystemColors.GrayText; } Font font = Font; text = GetItemText(item); if (SelectionMode != SelectionMode.None && (e.State & DrawItemState.Selected) == DrawItemState.Selected) { if (Enabled) { backColor = SystemColors.Highlight; foreColor = SystemColors.HighlightText; } else { backColor = SystemColors.InactiveBorder; foreColor = SystemColors.GrayText; } } // Draw the text // // Due to some sort of unpredictable painting optimization in the Windows ListBox control, // we need to always paint the background rectangle for the current line. using (Brush b = new SolidBrush(backColor)) { e.Graphics.FillRectangle(b, textBounds); } Rectangle stringBounds = new Rectangle( textBounds.X + 1, textBounds.Y, textBounds.Width - 1, textBounds.Height - border * 2); if( UseCompatibleTextRendering ){ using (StringFormat format = new StringFormat()) { if (UseTabStops) { // Set tab stops so it looks similar to a ListBox, at least with the default font size. float tabDistance = 3.6f * Font.Height; // about 7 characters float[] tabStops = new float[15]; float tabOffset = -(idealCheckSize + (border * 2)); for (int i = 1; i < tabStops.Length; i++) tabStops[i] = tabDistance; //(bug 111825) if (Math.Abs(tabOffset) < tabDistance) { tabStops[0] = tabDistance +tabOffset; } else { tabStops[0] = tabDistance; } format.SetTabStops(0, tabStops); } else if (UseCustomTabOffsets) { //Set TabStops to userDefined values int wpar = CustomTabOffsets.Count; float[] tabStops = new float[wpar]; CustomTabOffsets.CopyTo(tabStops, 0); format.SetTabStops(0, tabStops); } // Adjust string format for Rtl controls if (RightToLeft == RightToLeft.Yes) { format.FormatFlags |= StringFormatFlags.DirectionRightToLeft; } // ListBox doesn't word-wrap its items, so neither should CheckedListBox // format.FormatFlags |= StringFormatFlags.NoWrap; // VSWhidbey 95774: Set Trimming to None to prevent DrawString() from whacking the entire // string when there is only one character per tab included in the string. format.Trimming = StringTrimming.None; // Do actual drawing using (SolidBrush brush = new SolidBrush(foreColor)) { e.Graphics.DrawString(text, font, brush, stringBounds, format); } } } else{ TextFormatFlags flags = TextFormatFlags.Default; flags |= TextFormatFlags.NoPrefix; if (UseTabStops || UseCustomTabOffsets) { flags |= TextFormatFlags.ExpandTabs; } // Adjust string format for Rtl controls if (RightToLeft == RightToLeft.Yes) { flags |= TextFormatFlags.RightToLeft; flags |= TextFormatFlags.Right; } // Do actual drawing TextRenderer.DrawText(e.Graphics, text, font, stringBounds, foreColor, flags ); } // Draw the focus rect if required // if ((e.State & DrawItemState.Focus) == DrawItemState.Focus && (e.State & DrawItemState.NoFocusRect) != DrawItemState.NoFocusRect) { ControlPaint.DrawFocusRectangle(e.Graphics, textBounds, foreColor, backColor); } } } ////// /// protected override void OnBackColorChanged(EventArgs e) { base.OnBackColorChanged(e); if (IsHandleCreated) { SafeNativeMethods.InvalidateRect(new HandleRef(this, Handle), null, true); } } ///[To be supplied.] ////// /// protected override void OnFontChanged(EventArgs e) { // Update the item height // if (IsHandleCreated) { SendMessage(NativeMethods.LB_SETITEMHEIGHT, 0, ItemHeight); } // The base OnFontChanged will adjust the height of the CheckedListBox accordingly // base.OnFontChanged(e); } ///[To be supplied.] ////// /// This is the code that actually fires the "keyPress" event. The Checked /// ListBox overrides this to look for space characters, since we /// want to use those to check or uncheck items periodically. Don't /// forget to call base.OnKeyPress() to ensure that KeyPrese events /// are correctly fired for all other keys. /// ///protected override void OnKeyPress(KeyPressEventArgs e) { if (e.KeyChar == ' ' && SelectionMode != SelectionMode.None) { LbnSelChange(); } if (FormattingEnabled) //We want to fire KeyPress only when FormattingEnabled (this is a whidbey property) { base.OnKeyPress(e); } } /// /// /// This is the code that actually fires the itemCheck event. Don't /// forget to call base.onItemCheck() to ensure that itemCheck vents /// are correctly fired for all other keys. /// ///protected virtual void OnItemCheck(ItemCheckEventArgs ice) { if (onItemCheck != null) onItemCheck(this, ice); } /// /// /// protected override void OnMeasureItem(MeasureItemEventArgs e) { base.OnMeasureItem(e); // we'll use the ideal checkbox size plus enough for padding on the top // and bottom // if (e.ItemHeight < idealCheckSize + 2) { e.ItemHeight = idealCheckSize + 2; } } ///[To be supplied.] ////// /// Actually goes and fires the selectedIndexChanged event. Inheriting controls /// should use this to know when the event is fired [this is preferable to /// adding an event handler on yourself for this event]. They should, /// however, remember to call base.OnSelectedIndexChanged(e); to ensure the event is /// still fired to external listeners /// protected override void OnSelectedIndexChanged(EventArgs e) { base.OnSelectedIndexChanged(e); lastSelected = SelectedIndex; } ////// /// Reparses the objects, getting new text strings for them. /// ///protected override void RefreshItems() { Hashtable savedcheckedItems = new Hashtable(); for (int i =0; i < Items.Count ; i ++) { savedcheckedItems[i] = CheckedItems.GetCheckedState(i); } //call the base base.RefreshItems(); // restore the checkedItems... for (int j =0; j < Items.Count; j++) { CheckedItems.SetCheckedState(j, (CheckState)savedcheckedItems[j]); } } /// /// /// Sets the checked value of the given item. This value should be from /// the System.Windows.Forms.CheckState enumeration. /// public void SetItemCheckState(int index, CheckState value) { if (index < 0 || index >= Items.Count) { throw new ArgumentOutOfRangeException("index", SR.GetString(SR.InvalidArgument, "index", (index).ToString(CultureInfo.CurrentCulture))); } // valid values are 0-2 inclusive. if (!ClientUtils.IsEnumValid(value,(int)value, (int)CheckState.Unchecked, (int)CheckState.Indeterminate)){ throw new InvalidEnumArgumentException("value", (int)value, typeof(CheckState)); } CheckState currentValue = CheckedItems.GetCheckedState(index); if (value != currentValue) { ItemCheckEventArgs itemCheckEvent = new ItemCheckEventArgs(index, value, currentValue); OnItemCheck(itemCheckEvent); if (itemCheckEvent.NewValue != currentValue) { CheckedItems.SetCheckedState(index, itemCheckEvent.NewValue); InvalidateItem(index); } } } ////// /// Sets the checked value of the given item. This value should be a /// boolean. /// public void SetItemChecked(int index, bool value) { SetItemCheckState(index, value ? CheckState.Checked : CheckState.Unchecked); } ////// /// We need to get LBN_SELCHANGE notifications /// ///[ System.Security.Permissions.SecurityPermissionAttribute(System.Security.Permissions.SecurityAction.LinkDemand, Flags=System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode) ] protected override void WmReflectCommand(ref Message m) { switch (NativeMethods.Util.HIWORD(m.WParam)) { case NativeMethods.LBN_SELCHANGE: LbnSelChange(); // finally, fire the OnSelectionChange event. base.WmReflectCommand(ref m); break; case NativeMethods.LBN_DBLCLK: // We want double-clicks to change the checkstate on each click - just like the CheckBox control // LbnSelChange(); base.WmReflectCommand(ref m); break; default: base.WmReflectCommand(ref m); break; } } /// /// /// Handle keyboard input to prevent arrow keys from toggling /// checkboxes in CheckOnClick mode. /// ///private void WmReflectVKeyToItem(ref Message m) { int keycode = NativeMethods.Util.LOWORD(m.WParam); switch ((Keys)keycode) { case Keys.Up: case Keys.Down: case Keys.PageUp: case Keys.PageDown: case Keys.Home: case Keys.End: case Keys.Left: case Keys.Right: killnextselect = true; break; default: killnextselect = false; break; } m.Result = NativeMethods.InvalidIntPtr; } /// /// /// The listbox's window procedure. Inheriting classes can override this /// to add extra functionality, but should not forget to call /// base.wndProc(m); to ensure the button continues to function properly. /// ///[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected override void WndProc(ref Message m) { switch (m.Msg) { case NativeMethods.WM_REFLECT + NativeMethods.WM_CHARTOITEM: m.Result = NativeMethods.InvalidIntPtr; break; case NativeMethods.WM_REFLECT + NativeMethods.WM_VKEYTOITEM: WmReflectVKeyToItem(ref m); break; default: if (m.Msg == LBC_GETCHECKSTATE) { int item = (int)m.WParam; if (item < 0 || item >= Items.Count) { m.Result = (IntPtr)LB_ERROR; } else { m.Result = (IntPtr)(GetItemChecked(item) ? LB_CHECKED : LB_UNCHECKED); } } else if (m.Msg == LBC_SETCHECKSTATE) { int item = (int)m.WParam; int state = (int)m.LParam; if (item < 0 || item >= Items.Count || (state != LB_CHECKED && state != LB_UNCHECKED)) { m.Result = IntPtr.Zero; } else { SetItemChecked(item, (state == LB_CHECKED)); m.Result = (IntPtr)1; } } else { base.WndProc(ref m); } break; } } /// /// /// new public class ObjectCollection : ListBox.ObjectCollection { private CheckedListBox owner; ///[To be supplied.] ////// /// public ObjectCollection(CheckedListBox owner) : base(owner) { this.owner = owner; } ///[To be supplied.] ////// /// Lets the user add an item to the listbox with the given initial value /// for the Checked portion of the item. /// public int Add(object item, bool isChecked) { return Add(item, isChecked ? CheckState.Checked : CheckState.Unchecked); } ////// /// Lets the user add an item to the listbox with the given initial value /// for the Checked portion of the item. /// public int Add(object item, CheckState check) { //validate the enum that's passed in here // // Valid values are 0-2 inclusive. if (!ClientUtils.IsEnumValid(check, (int)check, (int)CheckState.Unchecked, (int)CheckState.Indeterminate)){ throw new InvalidEnumArgumentException("value", (int)check, typeof(CheckState)); } int index = base.Add(item); owner.SetItemCheckState(index, check); return index; } } ////// /// public class CheckedIndexCollection : IList { private CheckedListBox owner; internal CheckedIndexCollection(CheckedListBox owner) { this.owner = owner; } ///[To be supplied.] ////// /// Number of current checked items. /// public int Count { get { return owner.CheckedItems.Count; } } ////// object ICollection.SyncRoot { get { return this; } } /// /// bool ICollection.IsSynchronized { get { return false; } } /// /// bool IList.IsFixedSize { get { return true; } } /// /// /// public bool IsReadOnly { get { return true; } } ///[To be supplied.] ////// /// Retrieves the specified checked item. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int this[int index] { get { object identifier = InnerArray.GetEntryObject(index, CheckedItemCollection.AnyMask); return InnerArray.IndexOfIdentifier(identifier, 0); } } ////// object IList.this[int index] { get { return this[index]; } set { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } } /// /// int IList.Add(object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } /// /// void IList.Clear() { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } /// /// void IList.Insert(int index, object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } /// /// void IList.Remove(object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } /// /// void IList.RemoveAt(int index) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedIndexCollectionIsReadOnly)); } /// /// /// public bool Contains(int index) { return (IndexOf(index) != -1); } ///[To be supplied.] ////// bool IList.Contains(object index) { if (index is Int32) { return Contains((int)index); } else { return false; } } /// /// /// public void CopyTo(Array dest, int index) { int cnt = owner.CheckedItems.Count; for (int i = 0; i < cnt; i++) { dest.SetValue(this[i], i + index); } } ///[To be supplied.] ////// This is the item array that stores our data. We share this backing store /// with the main object collection. /// private ItemArray InnerArray { get { return ((ObjectCollection)owner.Items).InnerArray; } } ////// /// public IEnumerator GetEnumerator() { int[] indices = new int[this.Count]; CopyTo(indices, 0); return indices.GetEnumerator(); } ///[To be supplied.] ////// /// public int IndexOf(int index) { if (index >= 0 && index < owner.Items.Count) { object value = InnerArray.GetEntryObject(index, 0); return owner.CheckedItems.IndexOfIdentifier(value); } return -1; } ///[To be supplied.] ////// int IList.IndexOf(object index) { if (index is Int32) { return IndexOf((int)index); } else { return -1; } } } /// /// /// public class CheckedItemCollection : IList { internal static int CheckedItemMask = ItemArray.CreateMask(); internal static int IndeterminateItemMask = ItemArray.CreateMask(); internal static int AnyMask = CheckedItemMask | IndeterminateItemMask; private CheckedListBox owner; internal CheckedItemCollection(CheckedListBox owner) { this.owner = owner; } ///[To be supplied.] ////// /// Number of current checked items. /// public int Count { get { return InnerArray.GetCount(AnyMask); } } ////// This is the item array that stores our data. We share this backing store /// with the main object collection. /// private ItemArray InnerArray { get { return ((ListBox.ObjectCollection)owner.Items).InnerArray; } } ////// /// Retrieves the specified checked item. /// [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public object this[int index] { get { return InnerArray.GetItem(index, AnyMask); } set { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } } ////// object ICollection.SyncRoot { get { return this; } } /// /// bool ICollection.IsSynchronized { get { return false; } } /// /// bool IList.IsFixedSize { get { return true; } } /// /// /// public bool IsReadOnly { get { return true; } } ///[To be supplied.] ////// /// public bool Contains(object item) { return IndexOf(item) != -1; } ///[To be supplied.] ////// /// public int IndexOf(object item) { return InnerArray.IndexOf(item, AnyMask); } internal int IndexOfIdentifier(object item) { return InnerArray.IndexOfIdentifier(item, AnyMask); } ///[To be supplied.] ////// int IList.Add(object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } /// /// void IList.Clear() { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } /// /// void IList.Insert(int index, object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } /// /// void IList.Remove(object value) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } /// /// void IList.RemoveAt(int index) { throw new NotSupportedException(SR.GetString(SR.CheckedListBoxCheckedItemCollectionIsReadOnly)); } /// /// /// public void CopyTo(Array dest, int index) { int cnt = InnerArray.GetCount(AnyMask); for (int i = 0; i < cnt; i++) { dest.SetValue(InnerArray.GetItem(i, AnyMask), i + index); } } ///[To be supplied.] ////// This method returns if the actual item index is checked. The index is the index to the MAIN /// collection, not this one. /// internal CheckState GetCheckedState(int index) { bool isChecked = InnerArray.GetState(index, CheckedItemMask); bool isIndeterminate = InnerArray.GetState(index, IndeterminateItemMask); Debug.Assert(!isChecked || !isIndeterminate, "Can't be both checked and indeterminate. Somebody broke our state."); if (isIndeterminate) { return CheckState.Indeterminate; } else if (isChecked) { return CheckState.Checked; } return CheckState.Unchecked; } ////// /// public IEnumerator GetEnumerator() { return InnerArray.GetEnumerator(AnyMask, true); } ///[To be supplied.] ////// Same thing for GetChecked. /// internal void SetCheckedState(int index, CheckState value) { bool isChecked; bool isIndeterminate; switch(value) { case CheckState.Checked: isChecked = true; isIndeterminate = false; break; case CheckState.Indeterminate: isChecked = false; isIndeterminate = true; break; default: isChecked = false; isIndeterminate = false; break; } bool wasChecked = InnerArray.GetState(index, CheckedItemMask); bool wasIndeterminate = InnerArray.GetState(index, IndeterminateItemMask); InnerArray.SetState(index, CheckedItemMask, isChecked); InnerArray.SetState(index, IndeterminateItemMask, isIndeterminate); if (wasChecked != isChecked || wasIndeterminate != isIndeterminate) { // Raise a notify event that this item has changed. owner.AccessibilityNotifyClients(AccessibleEvents.StateChange, index); } } } ////// /// /// [System.Runtime.InteropServices.ComVisible(true)] internal class CheckedListBoxAccessibleObject : ControlAccessibleObject { ////// /// public CheckedListBoxAccessibleObject(CheckedListBox owner) : base(owner) { } private CheckedListBox CheckedListBox { get { return (CheckedListBox)Owner; } } ////// /// public override AccessibleObject GetChild(int index) { if (index >= 0 && index < CheckedListBox.Items.Count) { return new CheckedListBoxItemAccessibleObject(this.CheckedListBox.GetItemText(CheckedListBox.Items[index]), index, this); } else { return null; } } ////// /// public override int GetChildCount() { return CheckedListBox.Items.Count; } public override AccessibleObject GetFocused() { int index = CheckedListBox.FocusedIndex; if (index >= 0) { return GetChild(index); } return null; } public override AccessibleObject GetSelected() { int index = CheckedListBox.SelectedIndex; if (index >= 0) { return GetChild(index); } return null; } public override AccessibleObject HitTest(int x, int y) { // Within a child element? // int count = GetChildCount(); for(int index=0; index < count; ++index) { AccessibleObject child = GetChild(index); if (child.Bounds.Contains(x, y)) { return child; } } // Within the CheckedListBox bounds? // if (this.Bounds.Contains(x, y)) { return this; } return null; } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation direction) { if (GetChildCount() > 0) { if (direction == AccessibleNavigation.FirstChild) { return GetChild(0); } if (direction == AccessibleNavigation.LastChild) { return GetChild(GetChildCount() - 1); } } return base.Navigate(direction); } } ////// /// /// [System.Runtime.InteropServices.ComVisible(true)] internal class CheckedListBoxItemAccessibleObject : AccessibleObject { private string name; private int index; private CheckedListBoxAccessibleObject parent; public CheckedListBoxItemAccessibleObject(string name, int index, CheckedListBoxAccessibleObject parent) : base() { this.name = name; this.parent = parent; this.index = index; } public override Rectangle Bounds { get { Rectangle rect = ParentCheckedListBox.GetItemRectangle(index); // Translate rect to screen coordinates // NativeMethods.POINT pt = new NativeMethods.POINT(rect.X, rect.Y); UnsafeNativeMethods.ClientToScreen(new HandleRef(ParentCheckedListBox, ParentCheckedListBox.Handle), pt); return new Rectangle(pt.x, pt.y, rect.Width, rect.Height); } } public override string DefaultAction { get { if (ParentCheckedListBox.GetItemChecked(index)) { return SR.GetString(SR.AccessibleActionUncheck); } else { return SR.GetString(SR.AccessibleActionCheck); } } } private CheckedListBox ParentCheckedListBox { get { return(CheckedListBox)parent.Owner; } } public override string Name { get { return name; } set { name = value; } } public override AccessibleObject Parent { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { return parent; } } public override AccessibleRole Role { get { return AccessibleRole.CheckButton; } } public override AccessibleStates State { get { AccessibleStates state = AccessibleStates.Selectable | AccessibleStates.Focusable; // Checked state // switch (ParentCheckedListBox.GetItemCheckState(index)) { case CheckState.Checked: state |= AccessibleStates.Checked; break; case CheckState.Indeterminate: state |= AccessibleStates.Indeterminate; break; case CheckState.Unchecked: // No accessible state corresponding to unchecked break; } // Selected state // if (ParentCheckedListBox.SelectedIndex == index) { state |= AccessibleStates.Selected | AccessibleStates.Focused; } return state; } } public override string Value { [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] get { return ParentCheckedListBox.GetItemChecked(index).ToString(); } } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void DoDefaultAction() { ParentCheckedListBox.SetItemChecked(index, !ParentCheckedListBox.GetItemChecked(index)); } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override AccessibleObject Navigate(AccessibleNavigation direction) { // Down/Next // if (direction == AccessibleNavigation.Down || direction == AccessibleNavigation.Next) { if (index < parent.GetChildCount() - 1) { return parent.GetChild(index + 1); } } // Up/Previous // if (direction == AccessibleNavigation.Up || direction == AccessibleNavigation.Previous) { if (index > 0) { return parent.GetChild(index - 1); } } return base.Navigate(direction); } [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] public override void Select(AccessibleSelection flags) { try { ParentCheckedListBox.AccessibilityObject.GetSystemIAccessibleInternal().accSelect((int) flags, index + 1); } catch (ArgumentException) { // In Everett, the CheckedListBox accessible children did not have any selection capability. // In Whidbey, they delegate the selection capability to OLEACC. // However, OLEACC does not deal w/ several Selection flags: ExtendSelection, AddSelection, RemoveSelection. // OLEACC instead throws an ArgumentException. // Since Whidbey API's should not throw an exception in places where Everett API's did not, we catch // the ArgumentException and fail silently. } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NumberFormatter.cs
- PolicyStatement.cs
- XmlElementList.cs
- DebugTracing.cs
- XmlSchemaAnnotated.cs
- EventDescriptor.cs
- LinkedResourceCollection.cs
- nulltextnavigator.cs
- AnnotationService.cs
- HierarchicalDataTemplate.cs
- PhysicalFontFamily.cs
- AssertSection.cs
- FusionWrap.cs
- SchemaAttDef.cs
- IPEndPoint.cs
- HttpCapabilitiesSectionHandler.cs
- ClientConfigurationSystem.cs
- ToolTip.cs
- SmtpFailedRecipientsException.cs
- DataColumnMappingCollection.cs
- ExeConfigurationFileMap.cs
- PeerResolverMode.cs
- TextSelectionHelper.cs
- InputBuffer.cs
- NullRuntimeConfig.cs
- DBNull.cs
- HandlerBase.cs
- DataBinding.cs
- InputScopeAttribute.cs
- UnauthorizedWebPart.cs
- ActiveXHost.cs
- DocumentOrderQuery.cs
- CompositeDataBoundControl.cs
- ToggleButton.cs
- OperationContext.cs
- BoundField.cs
- FileStream.cs
- ComponentGuaranteesAttribute.cs
- AssemblySettingAttributes.cs
- _ShellExpression.cs
- NTAccount.cs
- ActivityBuilder.cs
- SystemParameters.cs
- Win32.cs
- ButtonFieldBase.cs
- Math.cs
- ContainerParaClient.cs
- ColumnCollection.cs
- ListViewInsertionMark.cs
- AttachedPropertiesService.cs
- Model3D.cs
- ConfigurationManagerHelperFactory.cs
- translator.cs
- SamlSecurityTokenAuthenticator.cs
- AttributeEmitter.cs
- DataTableReader.cs
- ResolveCriteriaCD1.cs
- XmlTextAttribute.cs
- KeyValueInternalCollection.cs
- GrammarBuilderPhrase.cs
- LineSegment.cs
- ConfigurationManager.cs
- UserValidatedEventArgs.cs
- EncryptedPackageFilter.cs
- HttpFileCollection.cs
- BaseWebProxyFinder.cs
- TextSearch.cs
- ChangeNode.cs
- DesignRelation.cs
- _CacheStreams.cs
- Assert.cs
- NotifyCollectionChangedEventArgs.cs
- HostedHttpContext.cs
- ArraySortHelper.cs
- Size.cs
- FormViewModeEventArgs.cs
- FormsAuthenticationCredentials.cs
- DynamicVirtualDiscoSearcher.cs
- NaturalLanguageHyphenator.cs
- EventSinkHelperWriter.cs
- OneToOneMappingSerializer.cs
- ColorTransform.cs
- AffineTransform3D.cs
- DesignerForm.cs
- Size.cs
- PropertyEmitter.cs
- XmlSchemaInclude.cs
- _TimerThread.cs
- OrderToken.cs
- XPathScanner.cs
- GridViewEditEventArgs.cs
- SimpleMailWebEventProvider.cs
- Pen.cs
- CachedRequestParams.cs
- SelectingProviderEventArgs.cs
- ApplicationInterop.cs
- StreamReader.cs
- PenThread.cs
- AddInEnvironment.cs
- TextBox.cs