RadioButton.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / RadioButton.cs / 1 / RadioButton.cs

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

/* 
 */ 
namespace System.Windows.Forms {
    using System.Runtime.InteropServices; 

    using System.Diagnostics;

    using System; 
    using System.Security.Permissions;
    using System.Windows.Forms.ButtonInternal; 
 
    using System.ComponentModel;
    using System.ComponentModel.Design; 

    using System.Drawing;
    using System.Windows.Forms.Internal;
 
    using System.Drawing.Drawing2D;
    using System.Windows.Forms.Layout; 
    using Microsoft.Win32; 

    ///  
    /// 
    ///    
    ///       Encapsulates a
    ///       standard 
    ///       Windows radio button (option button).
    ///     
    ///  
    [
    ComVisible(true), 
    ClassInterface(ClassInterfaceType.AutoDispatch),
    DefaultProperty("Checked"),
    DefaultEvent("CheckedChanged"),
    DefaultBindingProperty("Checked"), 
    ToolboxItem("System.Windows.Forms.Design.AutoSizeToolboxItem," + AssemblyRef.SystemDesign),
    Designer("System.Windows.Forms.Design.RadioButtonDesigner, " + AssemblyRef.SystemDesign), 
    SRDescription(SR.DescriptionRadioButton) 
    ]
    public class RadioButton : ButtonBase { 

        private static readonly object EVENT_CHECKEDCHANGED = new object();
        private static readonly ContentAlignment anyRight  = ContentAlignment.TopRight | ContentAlignment.MiddleRight | ContentAlignment.BottomRight;
 
        // Used to see if we need to iterate through the autochecked items and modify their tabstops.
        private bool firstfocus = true; 
        private bool isChecked; 
        private bool autoCheck = true;
        private ContentAlignment checkAlign = ContentAlignment.MiddleLeft; 
        private Appearance appearance        = System.Windows.Forms.Appearance.Normal;

        /// 
        ///  
        ///    
        ///       Initializes a new instance of the  
        ///       class. 
        ///    
        ///  
        public RadioButton() : base() {
            // Radiobuttons shouldn't respond to right clicks, so we need to do all our own click logic
            SetStyle(ControlStyles.StandardClick, false);
 
            TextAlign = ContentAlignment.MiddleLeft;
            TabStop = false; 
            SetAutoSizeMode(AutoSizeMode.GrowAndShrink); 
        }
 
        /// 
        /// 
        /// Gets or sets a value indicating whether the 
        /// value and the appearance of 
        /// the control automatically change when the control is clicked.
        ///  
        [ 
        DefaultValue(true),
        SRCategory(SR.CatBehavior), 
        SRDescription(SR.RadioButtonAutoCheckDescr)
        ]
        public bool AutoCheck {
            get { 
                return autoCheck;
            } 
 
            set {
                if (autoCheck != value) { 
                    autoCheck = value;
                    PerformAutoUpdates(false);
                }
            } 
        }
 
        ///  
        /// 
        ///     
        ///       Gets or sets the appearance of the radio
        ///       button
        ///       control is drawn.
        ///     
        /// 
        [ 
        DefaultValue(Appearance.Normal), 
        SRCategory(SR.CatAppearance),
        Localizable(true), 
        SRDescription(SR.RadioButtonAppearanceDescr)
        ]
        public Appearance Appearance {
            get { 
                return appearance;
            } 
 
            set {
                if (appearance != value) { 
                    //valid values are 0x0 to 0x1
                    if (!ClientUtils.IsEnumValid(value, (int)value, (int)Appearance.Normal, (int)Appearance.Button)){
                        throw new InvalidEnumArgumentException("value", (int)value, typeof(Appearance));
                    } 

                    using (LayoutTransaction.CreateTransactionIf(AutoSize, this.ParentInternal, this, PropertyNames.Appearance)) { 
                        appearance = value; 
                        if (OwnerDraw) {
                            Refresh(); 
                        }
                        else {
                            UpdateStyles();
                        } 

                        OnAppearanceChanged(EventArgs.Empty); 
                    } 
                }
            } 
        }

        private static readonly object EVENT_APPEARANCECHANGED = new object();
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [SRCategory(SR.CatPropertyChanged), SRDescription(SR.RadioButtonOnAppearanceChangedDescr)] 
        public event EventHandler AppearanceChanged {
            add {
                Events.AddHandler(EVENT_APPEARANCECHANGED, value);
            } 

            remove { 
                Events.RemoveHandler(EVENT_APPEARANCECHANGED, value); 
            }
        } 

        /// 
        /// 
        ///     
        ///       Gets or
        ///       sets the location of the check box portion of the 
        ///       radio button control. 
        ///
        ///     
        /// 
        [
        Localizable(true),
        SRCategory(SR.CatAppearance), 
        DefaultValue(ContentAlignment.MiddleLeft),
        SRDescription(SR.RadioButtonCheckAlignDescr) 
        ] 
        public ContentAlignment CheckAlign {
            get { 
                return checkAlign;
            }
            set {
                if (!WindowsFormsUtils.EnumValidator.IsValidContentAlignment(value)) { 
                    throw new InvalidEnumArgumentException("value", (int)value, typeof(ContentAlignment));
                } 
 
                checkAlign = value;
                if (OwnerDraw) { 
                    Invalidate();
                }
                else {
                    UpdateStyles(); 
                }
            } 
        } 

        ///  
        /// 
        ///    
        ///       Gets or sets a value indicating whether the
        ///       control is checked or not. 
        ///
        ///     
        ///  
        [
        Bindable(true), 
        SettingsBindable(true),
        DefaultValue(false),
        SRCategory(SR.CatAppearance),
        SRDescription(SR.RadioButtonCheckedDescr) 
        ]
        public bool Checked { 
            get { 
                return isChecked;
            } 

            set {
                if (isChecked != value) {
                    isChecked = value; 

                    if (IsHandleCreated) SendMessage(NativeMethods.BM_SETCHECK, value? 1: 0, 0); 
                    Invalidate(); 
                    Update();
                    PerformAutoUpdates(false); 
                    OnCheckedChanged(EventArgs.Empty);
                }
            }
        } 

        ///  
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick { 
            add {
                base.DoubleClick += value;
            }
            remove { 
                base.DoubleClick -= value;
            } 
        } 

        ///  
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick {
            add { 
                base.MouseDoubleClick += value;
            } 
            remove { 
                base.MouseDoubleClick -= value;
            } 
        }

        /// 
        ///  
        /// 
        ///  
        protected override CreateParams CreateParams { 
            [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)]
            get { 
                CreateParams cp = base.CreateParams;
                cp.ClassName = "BUTTON";
                if (OwnerDraw) {
                    cp.Style |= NativeMethods.BS_OWNERDRAW; 
                }
                else { 
                    cp.Style |= NativeMethods.BS_RADIOBUTTON; 
                    if (Appearance == Appearance.Button) {
                        cp.Style |= NativeMethods.BS_PUSHLIKE; 
                    }

                    // Determine the alignment of the radio button
                    // 
                    ContentAlignment align = RtlTranslateContent(CheckAlign);
                    if ((int)(align & anyRight) != 0) { 
                        cp.Style |= NativeMethods.BS_RIGHTBUTTON; 
                    }
                } 
                return cp;
            }
        }
 
        /// 
        ///  
        ///     Deriving classes can override this to configure a default size for their control. 
        ///     This is more efficient than setting the size in the control's constructor.
        ///  
        protected override Size DefaultSize {
            get {
                return new Size(104, 24);
            } 
        }
 
        internal override Size GetPreferredSizeCore(Size proposedConstraints) { 
            if(FlatStyle != FlatStyle.System) {
                return base.GetPreferredSizeCore(proposedConstraints); 
            }

            Size textSize = TextRenderer.MeasureText(this.Text, this.Font);
            Size size = SizeFromClientSize(textSize); 
            size.Width += 24;
            size.Height += 5; 
            return size; 
        }
 
        internal override Rectangle OverChangeRectangle {
            get {
                if (Appearance == Appearance.Button) {
                    return base.OverChangeRectangle; 
                }
                else { 
                    if (FlatStyle == FlatStyle.Standard) { 
                        // this Rectangle will cause no Invalidation
                        // can't use Rectangle.Empty because it will cause Invalidate(ClientRectangle) 
                        return new Rectangle(-1, -1, 1, 1);
                    }
                    else {
                        return Adapter.CommonLayout().Layout().checkBounds; 
                    }
                } 
            } 
        }
 
        internal override Rectangle DownChangeRectangle {
            get {
                if (Appearance == Appearance.Button || FlatStyle == FlatStyle.System) {
                    return base.DownChangeRectangle; 
                }
                else { 
                    return Adapter.CommonLayout().Layout().checkBounds; 
                }
            } 
        }

        /// 
        [DefaultValue(false)] 
        new public bool TabStop {
            get { 
                return base.TabStop; 
            }
            set { 
                base.TabStop = value;
            }
        }
 
        /// 
        ///  
        ///  
        ///    
        ///       Gets or sets the value indicating whether the user can give the focus to this 
        ///       control using the TAB key.
        ///
        ///    
        ///  
        [
        Localizable(true), 
        DefaultValue(ContentAlignment.MiddleLeft) 
        ]
        public override ContentAlignment TextAlign { 
            get {
                return base.TextAlign;
            }
            set { 
                base.TextAlign = value;
            } 
        } 

        ///  
        /// 
        ///    
        ///       Occurs when the
        ///       value of the  
        ///       property changes.
        ///     
        ///  
        [SRDescription(SR.RadioButtonOnCheckedChangedDescr)]
        public event EventHandler CheckedChanged { 
            add {
                Events.AddHandler(EVENT_CHECKEDCHANGED, value);
            }
            remove { 
                Events.RemoveHandler(EVENT_CHECKEDCHANGED, value);
            } 
        } 

        ///  
        /// 
        /// 
        ///    
        ///       Constructs the new instance of the accessibility object for this control. Subclasses 
        ///       should not call base.CreateAccessibilityObject.
        ///     
        ///  
        protected override AccessibleObject CreateAccessibilityInstance() {
            return new RadioButtonAccessibleObject(this); 
        }

        /// 
        ///  
        /// 
        ///  
        protected override void OnHandleCreated(EventArgs e) { 
            base.OnHandleCreated(e);
            //Since this is protected override, this can be called directly in a overriden class 
            //and the handle doesn't need to be created.
            //So check for the handle to improve performance
            if (IsHandleCreated) {
                SendMessage(NativeMethods.BM_SETCHECK, isChecked? 1: 0, 0); 
            }
        } 
 
        /// 
        ///  
        ///    
        ///       Raises the 
        ///       event.
        ///     
        /// 
        protected virtual void OnCheckedChanged(EventArgs e) { 
            AccessibilityNotifyClients(AccessibleEvents.StateChange, -1); 
            AccessibilityNotifyClients(AccessibleEvents.NameChange, -1);
            EventHandler handler = (EventHandler)Events[EVENT_CHECKEDCHANGED]; 
            if (handler != null) handler(this, e);
        }

        ///  
        /// 
        ///     We override this to implement the autoCheck functionality. 
        ///  
        /// 
        protected override void OnClick(EventArgs e) { 
            if (autoCheck) {
                Checked = true;
            }
            base.OnClick(e); 
        }
 
        ///  
        /// 
        ///  
        /// 
        protected override void OnEnter(EventArgs e) {
            // Just like the Win32 RadioButton, fire a click if the
            // user arrows onto the control.. 
            //
            if (MouseButtons == MouseButtons.None) { 
                if (UnsafeNativeMethods.GetKeyState((int)Keys.Tab) >= 0) { 
                    //We enter the radioButton by using arrow keys
                    //Paint in raised state... 
                    //
                    ResetFlagsandPaint();
                    if(!ValidationCancelled){
                        OnClick(e); 
                    }
                } 
                else { 
                    //we enter the radioButton by pressing Tab
                    PerformAutoUpdates(true); 
                    //reset the TabStop so we can come back later
                    //notice that PerformAutoUpdates will set the
                    //TabStop of this button to false
                    TabStop = true; 
                }
            } 
            base.OnEnter(e); 
        }
 
        /// 
        /// 
        /// 
        ///  
        private void PerformAutoUpdates(bool tabbedInto) {
            if (autoCheck) { 
                if (firstfocus) { 
                    WipeTabStops(tabbedInto);
                } 
                TabStop = isChecked;
                if (isChecked) {
                    Control parent = ParentInternal;
                    if (parent != null) { 
                        Control.ControlCollection children = parent.Controls;
                        for (int i = 0; i < children.Count; i++) { 
                            Control ctl = children[i]; 
                            if (ctl != this && ctl is RadioButton) {
                                RadioButton button = (RadioButton)ctl; 
                                if (button.autoCheck && button.Checked) {
                                    PropertyDescriptor propDesc = TypeDescriptor.GetProperties(this)["Checked"];
                                    propDesc.SetValue(button, false);
                                } 
                            }
                        } 
                    } 
                }
            } 
        }

        /// 
        ///  
        ///     Removes tabstops from all radio buttons, other than the one that currently has the focus.
        ///  
        ///  
        private void WipeTabStops(bool tabbedInto) {
 		    Control parent = ParentInternal; 
            if (parent != null) {
                Control.ControlCollection children = parent.Controls;
                for (int i = 0; i < children.Count; i++) {
                    Control ctl = children[i]; 
                    if (ctl is RadioButton) {
                        RadioButton button = (RadioButton) ctl; 
                        if (!tabbedInto) { 
                            button.firstfocus = false;
                        } 
                        if (button.autoCheck) {
                            button.TabStop = false;
                        }
                    } 
                }
            } 
        } 

        internal override ButtonBaseAdapter CreateFlatAdapter() { 
            return new RadioButtonFlatAdapter(this);
        }

        internal override ButtonBaseAdapter CreatePopupAdapter() { 
            return new RadioButtonPopupAdapter(this);
        } 
 
        internal override ButtonBaseAdapter CreateStandardAdapter() {
            return new RadioButtonStandardAdapter(this); 
        }

        private void OnAppearanceChanged(EventArgs e) {
            EventHandler eh = Events[EVENT_APPEARANCECHANGED] as EventHandler; 
            if (eh != null) {
                eh(this, e); 
            } 
        }
 
        /// 
        /// 
        /// 
        ///     
        ///       Raises the  event.
        /// 
        ///     
        /// 
        protected override void OnMouseUp(MouseEventArgs mevent) { 
            if (mevent.Button == MouseButtons.Left && GetStyle(ControlStyles.UserPaint)) {
                if (base.MouseIsDown) {
                    Point pt = PointToScreen(new Point(mevent.X, mevent.Y));
                    if (UnsafeNativeMethods.WindowFromPoint(pt.X, pt.Y) == Handle) { 
                        //Paint in raised state...
                        // 
                        ResetFlagsandPaint(); 
                        if (!ValidationCancelled) {
                            OnClick(mevent); 
                            OnMouseClick(mevent);
                        }

                    } 
                }
            } 
            base.OnMouseUp(mevent); 
        }
 
        /// 
        /// 
        ///    
        ///       Generates a  event for the 
        ///       button, simulating a click by a user.
        ///     
        ///  
        public void PerformClick() {
            if (CanSelect) { 
                //Paint in raised state...
                //
                ResetFlagsandPaint();
                if (!ValidationCancelled) { 
                    OnClick(EventArgs.Empty);
                } 
            } 

        } 

        /// 
        /// 
        ///  
        /// 
        [UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)] 
        protected internal override bool ProcessMnemonic(char charCode) { 
            if (UseMnemonic && IsMnemonic(charCode, Text) && CanSelect) {
                if (!Focused) { 
                    FocusInternal();    // This will cause an OnEnter event, which in turn will fire the click event
                }
                else {
                    PerformClick();     // Generate a click if already focused 
                }
                return true; 
            } 
            return false;
        } 

        /// 
        /// 
        ///     Returns a string representation for this control. 
        /// 
        ///  
        public override string ToString() { 

            string s = base.ToString(); 
            return s + ", Checked: " + Checked.ToString();
        }

        ///  
        /// 
        ///  
        ///  
        [System.Runtime.InteropServices.ComVisible(true)]
        public class RadioButtonAccessibleObject : ButtonBaseAccessibleObject { 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public RadioButtonAccessibleObject(RadioButton owner) : base(owner) { 
            } 

            ///  
            /// 
            ///    [To be supplied.]
            /// 
            public override string DefaultAction { 
                get {
                    string defaultAction = Owner.AccessibleDefaultActionDescription; 
                    if (defaultAction != null) { 
                        return defaultAction;
                    } 

                    return SR.GetString(SR.AccessibleActionCheck);
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public override AccessibleRole Role {
                get {
                    AccessibleRole role = Owner.AccessibleRole;
                    if (role != AccessibleRole.Default) { 
                        return role;
                    } 
                    return AccessibleRole.RadioButton; 
                }
            } 

            /// 
            /// 
            ///    [To be supplied.] 
            /// 
            public override AccessibleStates State { 
                get { 
                    if (((RadioButton)Owner).Checked) {
                        return AccessibleStates.Checked | base.State; 
                    }
                    return base.State;
                }
            } 

            ///  
            ///  
            ///    [To be supplied.]
            ///  
            [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
            public override void DoDefaultAction() {
                ((RadioButton)Owner).PerformClick();
            } 
        }
 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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