C# ListBox 變成 RadioListBox

C# ListBox 變成 RadioListBox

C# ListBox 變成 RadioListBox


資料來源: https://www.codeproject.com/Articles/18526/RadioListBox-A-ListBox-with-Radio-Buttons-Winforms


using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms.VisualStyles;

namespace System.Windows.Forms
{
    public class RadioListBox : ListBox
    {
        private StringFormat Align;
        private bool IsTransparent = false;
        private Brush BackBrush;

        // Allows the BackColor to be transparent
        public override Color BackColor
        {
            get
            {
                if (IsTransparent)
                    return Color.Transparent;
                else
                    return base.BackColor;
            }
            set
            {
                if (value == Color.Transparent)
                {
                    IsTransparent = true;
                    base.BackColor = (this.Parent == null) ? SystemColors.Window : this.Parent.BackColor;
                }
                else
                {
                    IsTransparent = false;
                    base.BackColor = value;
                }

                if (this.BackBrush != null)
                    this.BackBrush.Dispose();
                BackBrush = new SolidBrush(base.BackColor);

                Invalidate();
            }
        }

        // Hides these properties in the designer
        [Browsable(false)]
        public override DrawMode DrawMode
        {
            get
            {
                return base.DrawMode;
            }
            set
            {
                if (value != DrawMode.OwnerDrawFixed)
                    throw new Exception("Invalid value for DrawMode property");
                else
                    base.DrawMode = value;
            }
        }
        [Browsable(false)]
        public override SelectionMode SelectionMode
        {
            get
            {
                return base.SelectionMode;
            }
            set
            {
                if (value != SelectionMode.One)
                    throw new Exception("Invalid value for SelectionMode property");
                else
                    base.SelectionMode = value;
            }
        }

        // Public constructor
        public RadioListBox()
        {
            this.DrawMode = DrawMode.OwnerDrawFixed;
            this.SelectionMode = SelectionMode.One;
            this.ItemHeight = this.FontHeight;

            this.Align = new StringFormat(StringFormat.GenericDefault);
            this.Align.LineAlignment = StringAlignment.Center;

            // Force transparent analisys
            this.BackColor = this.BackColor;
        }

        // Main paiting method
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            int maxItem = this.Items.Count - 1;

            if (e.Index < 0 || e.Index > maxItem)
            {
                // Erase all background if control has no items
                e.Graphics.FillRectangle(BackBrush, this.ClientRectangle);
                return;
            }

            int size = e.Font.Height; // button size depends on font height, not on item height

            // Calculate bounds for background, if last item paint up to bottom of control
            Rectangle backRect = e.Bounds;
            if (e.Index == maxItem)
                backRect.Height = this.ClientRectangle.Top + this.ClientRectangle.Height - e.Bounds.Top;
            e.Graphics.FillRectangle(BackBrush, backRect);

            // Determines text color/brush
            Brush textBrush;
            bool isChecked = (e.State & DrawItemState.Selected) == DrawItemState.Selected;

            RadioButtonState state = isChecked ? RadioButtonState.CheckedNormal : RadioButtonState.UncheckedNormal;
            if ((e.State & DrawItemState.Disabled) == DrawItemState.Disabled)
            {
                textBrush = SystemBrushes.GrayText;
                state = isChecked ? RadioButtonState.CheckedDisabled : RadioButtonState.UncheckedDisabled;
            }
            else if ((e.State & DrawItemState.Grayed) == DrawItemState.Grayed)
            {
                textBrush = SystemBrushes.GrayText;
                state = isChecked ? RadioButtonState.CheckedDisabled : RadioButtonState.UncheckedDisabled;
            }
            else
            {
                textBrush = SystemBrushes.FromSystemColor(this.ForeColor);
            }

            // Determines bounds for text and radio button
            Size glyphSize = RadioButtonRenderer.GetGlyphSize(e.Graphics, state);
            Point glyphLocation = e.Bounds.Location;
            glyphLocation.Y += (e.Bounds.Height - glyphSize.Height) / 2;

            Rectangle bounds = new Rectangle(e.Bounds.X + glyphSize.Width, e.Bounds.Y, e.Bounds.Width - glyphSize.Width, e.Bounds.Height);

            // Draws the radio button
            RadioButtonRenderer.DrawRadioButton(e.Graphics, glyphLocation, state);

            // Draws the text
            if (!string.IsNullOrEmpty(DisplayMember)) // Bound Datatable? Then show the column written in Displaymember
                e.Graphics.DrawString(((System.Data.DataRowView)this.Items[e.Index])[this.DisplayMember].ToString(),
                    e.Font, textBrush, bounds, this.Align);
            else
                e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font, textBrush, bounds, this.Align);

            // If the ListBox has focus, draw a focus rectangle around the selected item.
            e.DrawFocusRectangle();
        }

        // Prevent background erasing
        protected override void DefWndProc(ref Message m)
        {
            if (m.Msg == 0x0014)  // WM_ERASEBKGND
            {
                m.Result = (IntPtr)1; // avoid default background erasing
                return;
            }

            base.DefWndProc(ref m);
        }

        // Other event handlers
        protected override void OnHandleCreated(EventArgs e)
        {
            if (this.FontHeight > this.ItemHeight)
                this.ItemHeight = this.FontHeight;

            base.OnHandleCreated(e);
        }
        protected override void OnFontChanged(EventArgs e)
        {
            base.OnFontChanged(e);

            if (this.FontHeight > this.ItemHeight)
                this.ItemHeight = this.FontHeight;
            Update();
        }
        protected override void OnParentChanged(EventArgs e)
        {
            // Force to change backcolor
            this.BackColor = this.BackColor;
        }
        protected override void OnParentBackColorChanged(EventArgs e)
        {
            // Force to change backcolor
            this.BackColor = this.BackColor;
        }
    }
}

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *