DomainUpDown.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / DomainUpDown.cs / 1305376 / DomainUpDown.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Windows.Forms { 
 
    using System.Diagnostics;
 
    using System;
    using System.Security.Permissions;

    using System.Runtime.InteropServices; 
    using System.ComponentModel;
    using System.Drawing; 
    using System.Drawing.Design; 
    using System.Globalization;
    using System.Windows.Forms.Layout; 
    using System.Collections;
    using Microsoft.Win32;

    ///  
    /// 
    ///    Represents a Windows up-down control that displays string values. 
    ///  
    [
    ComVisible(true), 
    ClassInterface(ClassInterfaceType.AutoDispatch),
    DefaultProperty("Items"),
    DefaultEvent("SelectedItemChanged"),
    DefaultBindingProperty("SelectedItem"), 
    SRDescription(SR.DescriptionDomainUpDown)
    ] 
    public class DomainUpDown : UpDownBase { 

        private readonly static string     DefaultValue = ""; 
        private readonly static bool       DefaultWrap = false;

        //////////////////////////////////////////////////////////////
        // Member variables 
        //
        ////////////////////////////////////////////////////////////// 
 
        /// 
        ///  
        ///     Allowable strings for the domain updown.
        /// 

        private DomainUpDownItemCollection domainItems = null; 

        private string stringValue = DefaultValue;      // Current string value 
        private int domainIndex = -1;                    // Index in the domain list 
        private bool sorted = false;                 // Sort the domain values
 
        private bool wrap = DefaultWrap;             // Wrap around domain items

        private EventHandler onSelectedItemChanged = null;
 
        private bool inSort = false;
 
        ///  
        /// 
        ///     
        ///       Initializes a new instance of the  class.
        ///    
        /// 
        public DomainUpDown() : base() { 
            // this class overrides GetPreferredSizeCore, let Control automatically cache the result
            SetState2(STATE2_USEPREFERREDSIZECACHE, true); 
            Text = String.Empty; 
        }
 
        // Properties

        /// 
        ///  
        ///    
        ///       Gets the collection of objects assigned to the 
        ///       up-down control. 
        ///    
        ///  
        [
        SRCategory(SR.CatData),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
        SRDescription(SR.DomainUpDownItemsDescr), 
        Localizable(true),
        Editor("System.Windows.Forms.Design.StringCollectionEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)) 
        ] 
        public DomainUpDownItemCollection Items {
 
            get {
                if (domainItems == null) {
                    domainItems = new DomainUpDownItemCollection(this);
                } 
                return domainItems;
            } 
        } 

        ///  
        /// 
        ///    
        ///    [To be supplied.]
        ///     
        /// 
        [ 
        Browsable(false), 
        EditorBrowsable(EditorBrowsableState.Never),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public new Padding Padding {
            get { return base.Padding; }
            set { base.Padding = value;} 
        }
 
        [ 
        Browsable(false),
        EditorBrowsable(EditorBrowsableState.Never) 
        ]
        public new event EventHandler PaddingChanged {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets the index value of the selected item.
        ///    
        /// 
        [ 
        Browsable(false),
        DefaultValue(-1), 
        SRCategory(SR.CatAppearance), 
        SRDescription(SR.DomainUpDownSelectedIndexDescr)
        ] 
        public int SelectedIndex {

            get {
                if (UserEdit) { 
                    return -1;
                } 
                else { 
                    return domainIndex;
                } 
            }

            set {
                if (value < -1 || value >= Items.Count) { 
                    throw new ArgumentOutOfRangeException("SelectedIndex", SR.GetString(SR.InvalidArgument, "SelectedIndex", (value).ToString(CultureInfo.CurrentCulture)));
                } 
 
                if (value != SelectedIndex) {
                    SelectIndex(value); 
                }
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets the selected item based on the index value
        ///       of the selected item in the 
        ///       collection.
        ///    
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        SRDescription(SR.DomainUpDownSelectedItemDescr) 
        ]
        public object SelectedItem { 
            get {
                int index = SelectedIndex;
                return(index == -1) ? null : Items[index];
            } 
            set {
 
                // Treat null as selecting no item 
                //
                if (value == null) { 
                    SelectedIndex = -1;
                }
                else {
                    // Attempt to find the given item in the list of items 
                    //
                    for (int i = 0; i < Items.Count; i++) { 
                        if (value != null && value.Equals(Items[i])) { 
                            SelectedIndex = i;
                            break; 
                        }
                    }
                }
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets a value indicating whether the item collection is sorted.
        ///    
        /// 
        [ 
        SRCategory(SR.CatBehavior),
        DefaultValue(false), 
        SRDescription(SR.DomainUpDownSortedDescr) 
        ]
        public bool Sorted { 

            get {
                return sorted;
            } 

            set { 
                sorted = value; 
                if (sorted) {
                    SortDomainItems(); 
                }
            }
        }
 
        /// 
        ///  
        ///     
        ///       Gets or sets a value indicating whether the collection of items continues to
        ///       the first or last item if the user continues past the end of the list. 
        ///    
        /// 
        [
        SRCategory(SR.CatBehavior), 
        Localizable(true),
        DefaultValue(false), 
        SRDescription(SR.DomainUpDownWrapDescr) 
        ]
        public bool Wrap { 

            get {
                return wrap;
            } 

            set { 
                wrap = value; 
            }
        } 

        //////////////////////////////////////////////////////////////
        // Methods
        // 
        //////////////////////////////////////////////////////////////
 
        ///  
        /// 
        ///     
        ///       Occurs when the  property has
        ///       been changed.
        ///    
        ///  
        [SRCategory(SR.CatBehavior), SRDescription(SR.DomainUpDownOnSelectedItemChangedDescr)]
        public event EventHandler SelectedItemChanged { 
            add { 
                onSelectedItemChanged += value;
            } 
            remove {
                onSelectedItemChanged -= value;
            }
        } 

        ///  
        ///  
        /// 
        ///    Constructs the new instance of the accessibility object for this control. Subclasses 
        ///    should not call base.CreateAccessibilityObject.
        /// 
        protected override AccessibleObject CreateAccessibilityInstance() {
            return new DomainUpDownAccessibleObject(this); 
        }
 
        ///  
        /// 
        ///     
        ///       Displays the next item in the object collection.
        ///    
        /// 
        public override void DownButton() { 

            // Make sure domain values exist, and there are >0 items 
            // 
            if (domainItems == null) {
                return; 
            }
            if (domainItems.Count <= 0) {
                return;
            } 

            // If the user has entered text, attempt to match it to the domain list 
            // 
            int matchIndex = -1;
            if (UserEdit) { 
                matchIndex = MatchIndex(Text, false, domainIndex);
            }
            if (matchIndex != -1) {
 
                // Found a match, so select this value
                // 
                SelectIndex(matchIndex); 
            }
 
            // Otherwise, get the next string in the domain list
            //
            else {
                if (domainIndex < domainItems.Count - 1) { 
                    SelectIndex(domainIndex + 1);
                } 
                else if (Wrap) { 
                    SelectIndex(0);
                } 
            }
        }

        ///  
        /// 
        ///     Tries to find a match of the supplied text in the domain list. 
        ///     If complete is true, a complete match is required for success 
        ///     (i.e. the supplied text is the same length as the matched domain value)
        ///     Returns the index in the domain list if the match is successful, 
        ///     returns -1 otherwise.
        /// 

        internal int MatchIndex(string text, bool complete) { 
            return MatchIndex(text, complete, domainIndex);
        } 
 
        internal int MatchIndex(string text, bool complete, int startPosition) {
 
            // Make sure domain values exist
            if (domainItems == null) {
                return -1;
            } 

            // Sanity check of parameters 
            if (text.Length < 1) { 
                return -1;
            } 
            if (domainItems.Count <= 0) {
                return -1;
            }
            if (startPosition < 0) { 
                startPosition = domainItems.Count - 1;
            } 
            if (startPosition >= domainItems.Count) { 
                startPosition = 0;
            } 

            // Attempt to match the supplied string text with
            // the domain list. Returns the index in the list if successful,
            // otherwise returns -1. 
            int index = startPosition;
            int matchIndex = -1; 
            bool found = false; 

            if (!complete) { 
                text = text.ToUpper(CultureInfo.InvariantCulture);
            }

            // Attempt to match the string with Items[index] 
            do {
                if (complete) 
                    found = Items[index].ToString().Equals(text); 
                else
                    found = Items[index].ToString().ToUpper(CultureInfo.InvariantCulture).StartsWith(text); 

                if (found) {
                    matchIndex = index;
                } 

                // Calculate the next index to attempt to match 
                index++; 
                if (index >= domainItems.Count) {
                    index = 0; 
                }

            } while (!found && index != startPosition);
 
            return matchIndex;
        } 
 
        /// 
        ///  
        /// 
        ///    
        ///       In the case of a DomainUpDown, the handler for changing
        ///       values is called OnSelectedItemChanged - so just forward it to that 
        ///       function.
        ///     
        ///  
        protected override void OnChanged(object source, EventArgs e) {
            OnSelectedItemChanged(source, e); 
        }

        /// 
        ///  
        /// 
        /// Handles the  
        /// event, using the input character to find the next matching item in our 
        /// item collection.
        ///  
        protected override void OnTextBoxKeyPress(object source, KeyPressEventArgs e) {
            if (ReadOnly) {
                char[] character = new char[] { e.KeyChar };
                UnicodeCategory uc = Char.GetUnicodeCategory(character[0]); 

                if (uc == UnicodeCategory.LetterNumber 
                    || uc == UnicodeCategory.LowercaseLetter 
                    || uc == UnicodeCategory.DecimalDigitNumber
                    || uc == UnicodeCategory.MathSymbol 
                    || uc == UnicodeCategory.OtherLetter
                    || uc == UnicodeCategory.OtherNumber
                    || uc == UnicodeCategory.UppercaseLetter) {
 
                    // Attempt to match the character to a domain item
                    int matchIndex = MatchIndex(new string(character), false, domainIndex + 1); 
                    if (matchIndex != -1) { 

                        // Select the matching domain item 
                        SelectIndex(matchIndex);
                    }
                    e.Handled = true;
                } 
            }
            base.OnTextBoxKeyPress(source, e); 
        } 

 
        /// 
        /// 
        ///    
        ///       Raises the  event. 
        ///    
        ///  
        protected void OnSelectedItemChanged(object source, EventArgs e) { 

            // Call the event handler 
            if (onSelectedItemChanged != null) {
                onSelectedItemChanged(this, e);
            }
        } 

        ///  
        ///  
        ///     Selects the item in the domain list at the given index
        ///  
        private void SelectIndex(int index) {

            // Sanity check index
 
            Debug.Assert(domainItems != null, "Domain values array is null");
            Debug.Assert(index < domainItems.Count && index >= -1, "SelectValue: index out of range"); 
            if (domainItems == null || index < -1 || index >= domainItems.Count) { 
                // Defensive programming
                index = -1; 
                return;
            }

            // If the selected index has changed, update the text 
            //
            domainIndex = index; 
            if (domainIndex >= 0) { 
                stringValue = domainItems[domainIndex].ToString();
                UserEdit = false; 
                UpdateEditText();
            }
            else {
                UserEdit = true; 
            }
 
            Debug.Assert(domainIndex >=0 || UserEdit == true, "UserEdit should be true when domainIndex < 0 " + UserEdit); 
        }
 
        /// 
        /// 
        ///     Sorts the domain values
        ///  
        private void SortDomainItems() {
            if (inSort) 
                return; 

            inSort = true; 
            try {
                // Sanity check
                Debug.Assert(sorted == true, "Sorted == false");
                if (!sorted) { 
                    return;
                } 
 
                if (domainItems != null) {
 
                    // Sort the domain values
                    ArrayList.Adapter(domainItems).Sort(new DomainUpDownItemCompare());

                    // Update the domain index 
                    if (!UserEdit) {
                        int newIndex = MatchIndex(stringValue, true); 
                        if (newIndex != -1) { 
                            SelectIndex(newIndex);
                        } 
                    }
                }
            }
            finally { 
                inSort = false;
            } 
        } 

        ///  
        /// 
        ///     Provides some interesting info about this control in String form.
        /// 
        ///  
        public override string ToString() {
 
            string s = base.ToString(); 

            if (Items != null) { 
                s += ", Items.Count: " + Items.Count.ToString(CultureInfo.CurrentCulture);
                s += ", SelectedIndex: " + SelectedIndex.ToString(CultureInfo.CurrentCulture);
            }
            return s; 
        }
 
        ///  
        /// 
        ///     
        ///       Displays the previous item in the collection.
        ///    
        /// 
        public override void UpButton() { 

            // Make sure domain values exist, and there are >0 items 
            if (domainItems == null) { 
                return;
            } 
            if (domainItems.Count <= 0) {
                return;
            }
            if (domainIndex == -1) { 
                return;
            } 
 
            // If the user has entered text, attempt to match it to the domain list
            int matchIndex = -1; 
            if (UserEdit) {
                matchIndex = MatchIndex(Text, false, domainIndex);
            }
            if (matchIndex != -1) { 

                // Found a match, so set the domain index accordingly 
                SelectIndex(matchIndex); 
            }
 
            // Otherwise, get the previous string in the domain list
            else {
                if (domainIndex > 0) {
                    SelectIndex(domainIndex - 1); 
                }
                else if (Wrap) { 
                    SelectIndex(domainItems.Count - 1); 
                }
            } 
        }

        /// 
        ///  
        ///    
        ///       Updates the text in the up-down control to display the selected item. 
        ///     
        /// 
        protected override void UpdateEditText() { 

            Debug.Assert(!UserEdit, "UserEdit should be false");
            // Defensive programming
            UserEdit = false; 

            ChangingText = true; 
            Text = stringValue; 
        }
        // This is not a breaking change -- Even though this control previously autosized to hieght, 
        // it didn't actually have an AutoSize property.  The new AutoSize property enables the
        // smarter behavior.
        internal override Size GetPreferredSizeCore(Size proposedConstraints) {
            int height = PreferredHeight; 
            int width = LayoutUtils.OldGetLargestStringSizeInCollection(Font, Items).Width;
 
            // AdjuctWindowRect with our border, since textbox is borderless. 
            width = SizeFromClientSize(width, height).Width + upDownButtons.Width;
            return new Size(width, height) + Padding.Size; 
        }

        // DomainUpDown collection class
 
        /// 
        ///  
        /// Encapsulates a collection of objects for use by the  
        /// class.
        ///  
        public class DomainUpDownItemCollection : ArrayList {
            DomainUpDown owner;

            internal DomainUpDownItemCollection(DomainUpDown owner) 
            : base() {
                this.owner = owner; 
            } 

            ///  
            /// 
            /// 
            [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
            public override object this[int index] { 
                get {
                    return base[index]; 
                } 

                set { 
                    base[index] = value;

                    if (owner.SelectedIndex == index) {
                        owner.SelectIndex(index); 
                    }
 
                    if (owner.Sorted) { 
                        owner.SortDomainItems();
                    } 
                }
            }

            ///  
            /// 
            ///  
            public override int Add(object item) { 
                // Overridden to perform sorting after adding an item
 
                int ret = base.Add(item);
                if (owner.Sorted) {
                    owner.SortDomainItems();
                } 
                return ret;
            } 
 
            /// 
            ///  
            /// 
            public override void Remove(object item) {
                int index = IndexOf(item);
 
                if (index == -1) {
                    throw new ArgumentOutOfRangeException("item", SR.GetString(SR.InvalidArgument, "item", item.ToString())); 
                } 
                else {
                    RemoveAt(index); 
                }
            }

            ///  
            /// 
            ///  
            public override void RemoveAt(int item) { 
                // Overridden to update the domain index if neccessary
                base.RemoveAt(item); 

                if (item < owner.domainIndex) {
                    // The item removed was before the currently selected item
                    owner.SelectIndex(owner.domainIndex - 1); 
                }
                else if (item == owner.domainIndex) { 
                    // The currently selected item was removed 
                    //
                    owner.SelectIndex(-1); 
                }
            }

            ///  
            /// 
            ///  
            public override void Insert(int index, object item) { 
                base.Insert(index, item);
                if (owner.Sorted) { 
                    owner.SortDomainItems();
                }
            }
        } // end class DomainUpDownItemCollection 

        ///  
        ///  
        /// 
        private sealed class DomainUpDownItemCompare : IComparer { 

            public int Compare(object p, object q) {
                if (p == q) return 0;
                if (p == null || q == null) { 
                    return 0;
                } 
 
                return String.Compare(p.ToString(), q.ToString(), false, CultureInfo.CurrentCulture);
            } 
        }

        /// 
        ///  
        /// 
        ///  
        [System.Runtime.InteropServices.ComVisible(true)] 
        public class DomainUpDownAccessibleObject : ControlAccessibleObject {
 
            private DomainItemListAccessibleObject itemList;

            /// 
            ///  
            /// 
            public DomainUpDownAccessibleObject(Control owner) : base(owner) { 
            } 

            private DomainItemListAccessibleObject ItemList { 
                get {
                    if (itemList == null) {
                        itemList = new DomainItemListAccessibleObject(this);
                    } 
                    return itemList;
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public override AccessibleRole Role { 
                get {
                    AccessibleRole role = Owner.AccessibleRole; 
                    if (role != AccessibleRole.Default) { 
                        return role;
                    } 
                    return AccessibleRole.ComboBox;
                }
            }
 
            /// 
            ///  
            ///  
            public override AccessibleObject GetChild(int index) {
                switch(index) { 
                    // TextBox child
                    //
                    case 0:
                        return ((UpDownBase)Owner).TextBox.AccessibilityObject.Parent; 

                    // Up/down buttons 
                    // 
                    case 1:
                        return ((UpDownBase)Owner).UpDownButtonsInternal.AccessibilityObject.Parent; 

                    case 2:
                        return ItemList;
                } 

                return null; 
            } 

            ///  
            /// 
            /// 
            public override int GetChildCount() {
                return 3; 
            }
        } 
 
        internal class DomainItemListAccessibleObject : AccessibleObject {
 
            private DomainUpDownAccessibleObject parent;

            public DomainItemListAccessibleObject(DomainUpDownAccessibleObject parent) : base() {
                this.parent = parent; 
            }
 
            public override string Name { 
                get {
                    string baseName = base.Name; 
                    if (baseName == null || baseName.Length == 0) {
                        return "Items";
                    }
                    return baseName; 
                }
                set { 
                    base.Name = value; 
                }
            } 

            public override AccessibleObject Parent {
                [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                get { 
                    return parent;
                } 
            } 

            public override AccessibleRole Role { 
                get {
                    return AccessibleRole.List;
                }
            } 

            public override AccessibleStates State { 
                get { 
                    return AccessibleStates.Invisible | AccessibleStates.Offscreen;
                } 
            }

            public override AccessibleObject GetChild(int index) {
 
                if (index >=0 && index < GetChildCount()) {
                    return new DomainItemAccessibleObject(((DomainUpDown)parent.Owner).Items[index].ToString(), this); 
                } 

                return null; 
            }

            public override int GetChildCount() {
                return ((DomainUpDown)parent.Owner).Items.Count; 
            }
 
        } 

        ///  
        /// 
        /// 
        /// 
        [System.Runtime.InteropServices.ComVisible(true)] 
        public class DomainItemAccessibleObject : AccessibleObject {
 
            private string name; 
            private DomainItemListAccessibleObject parent;
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public DomainItemAccessibleObject(string name, AccessibleObject parent) : base() {
                this.name = name; 
                this.parent = (DomainItemListAccessibleObject)parent; 
            }
 
            /// 
            /// 
            ///    [To be supplied.]
            ///  
            public override string Name {
                get { 
                    return name; 
                }
                set { 
                    name = value;
                }
            }
 
            /// 
            ///  
            ///    [To be supplied.] 
            /// 
            public override AccessibleObject Parent { 
                [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                get {
                    return parent;
                } 
            }
 
            ///  
            /// 
            ///    [To be supplied.] 
            /// 
            public override AccessibleRole Role {
                get {
                    return AccessibleRole.ListItem; 
                }
            } 
 
            /// 
            ///  
            ///    [To be supplied.]
            /// 
            public override AccessibleStates State {
                get { 
                    return AccessibleStates.Selectable;
                } 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public override string Value { 
                [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
                get { 
                    return name; 
                }
            } 
        }

    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK