Add a badge to a C# winforms control

前端 未结 3 1619
暖寄归人
暖寄归人 2020-12-11 13:24

When writing in CSS I can add a class of \"badge\" and get what I want. A small number near a button or tab with some styling to it, to show that this control has pending in

相关标签:
3条回答
  • 2020-12-11 13:44

    And here is a way with a static Adorner class, very quick and rather dirty..

    It can add a Label to many controls and it includes a click action, dynamic text and has code to remove the Label.

    an adorned button

    Adding a Badge to a Button takes one line:

        public Form1()
        {
            InitializeComponent();
            // adorn one Button with a Badge Label:
            Adorner.AddBadgeTo(button1, "123");
            // if you want to you can add a click action:
            Adorner.SetClickAction(button1, dobidoo);
        }
    
        // a test action
        void dobidoo(Control ctl)
        {
            Console.WriteLine("You have clicked on :" + ctl.Text);
        }
    

    Here is the Adorner class:

    static class Adorner
    {
        private static List<Control> controls = new List<Control>();
    
        static public bool AddBadgeTo(Control ctl, string Text)
        {
            if (controls.Contains(ctl)) return false;
    
            Badge badge = new Badge();
            badge.AutoSize = true;
            badge.Text = Text;
            badge.BackColor = Color.Transparent;
            controls.Add(ctl);
            ctl.Controls.Add(badge);
            SetPosition(badge, ctl);
    
            return true;
        }
    
        static public bool RemoveBadgeFrom(Control ctl)
        {
            Badge badge = GetBadge(ctl);
            if (badge != null)
            {
                ctl.Controls.Remove(badge);
                controls.Remove(ctl);
                return true;
            }
            else return false;
        }
    
        static public void SetBadgeText(Control ctl, string newText)
        {
            Badge badge = GetBadge(ctl);
            if (badge != null) 
            {
                    badge.Text = newText;
                    SetPosition(badge, ctl);
            }
        }
    
        static public string GetBadgeText(Control ctl)
        {
            Badge badge = GetBadge(ctl);
            if (badge != null) return badge.Text;
            return "";
        }
    
        static private void SetPosition(Badge badge, Control ctl)
        {
           badge.Location = new Point(ctl.Width  - badge.Width - 5, 
                                      ctl.Height - badge.Height - 5);
        }
    
        static public void SetClickAction(Control ctl, Action<Control> action)
        {
            Badge badge = GetBadge(ctl);
            if (badge != null)  badge.ClickEvent = action;
        }
    
        static Badge GetBadge(Control ctl)
        {
            for (int c = 0; c < ctl.Controls.Count; c++)
                if (ctl.Controls[c] is Badge) return ctl.Controls[c] as Badge;
            return null;
        }
    
    
        class Badge : Label
        {
            Color BackColor = Color.SkyBlue;
            Color ForeColor = Color.White;
            Font font = new Font("Sans Serif", 8f);
    
            public Action<Control> ClickEvent;
    
            public Badge()   {}
    
            protected override void OnPaint(PaintEventArgs e)
            {
                e.Graphics.FillEllipse(new SolidBrush(BackColor), this.ClientRectangle);
                e.Graphics.DrawString(Text, font, new SolidBrush(ForeColor), 3, 1);
            }
    
            protected override void OnClick(EventArgs e)
            {
                ClickEvent(this);
            }
    
        }
    }
    

    Note that while you can add it to most controls, not all work as well as a Button. A TabControl is rather hard to adorn as its Tabs really are not Controls but just painted areas, so just like adding a 'close X' to it you would have to user draw the badges of all TabPages..

    0 讨论(0)
  • 2020-12-11 14:01

    Here is a rough way to do it with a UserControl:

    public partial class btnControl : UserControl
        {
            public Label label = new Label();
            public TextBox box = new TextBox();
    
            public btnControl()
            {
                this.label = new System.Windows.Forms.Label();
                this.box = new System.Windows.Forms.TextBox();
                this.SuspendLayout();
                // 
                // label
                // 
                this.label.AutoSize = true;
                this.label.ForeColor = System.Drawing.Color.White;
                this.label.Location = new System.Drawing.Point(4, 7);
                this.label.Name = "label";
                this.label.Size = new System.Drawing.Size(35, 13);
                this.label.TabIndex = 0;
                this.label.Text = "label";
                // 
                // box
                // 
                this.box.Location = new System.Drawing.Point(110, 3);
                this.box.Name = "box";
                this.box.Size = new System.Drawing.Size(31, 20);
                this.box.TabIndex = 1;
                this.box.Enabled = false;
                // 
                // btnControl
                // 
                this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.BackColor = System.Drawing.Color.Blue;
                this.Controls.Add(this.box);
                this.Controls.Add(this.label);
                this.Name = "btnControl";
                this.Size = new System.Drawing.Size(144, 26);
                this.ResumeLayout(false);
                this.PerformLayout();
            }
        }
    

    Then put it in your form:

    private void Form1_Load(object sender, EventArgs e)
            {
                btnControl Control = new btnControl();
                this.Controls.Add(Control);
                Control.label.Text = "Home";
                Control.box.Text = "42";
            }
    

    Gives you:

    enter image description here

    0 讨论(0)
  • 2020-12-11 14:11

    Really the easiest and best way to achieve this is to create a new customized UserControl. Just add a button and insert a label over it on the right. Then add getters and setters for the controls inside you new UserControl. Here's an example of get/set to configure the button's notification:

    public String ButtonNotification {
       get { return yourUserControlLabel.Text; }
       set {
             if (value == null || value == "") { yourUserControlLabel.Visibility = Hidden; }
             else { yourUserControlLabel.Visibility = Visible; }
    
             yourUserControlLabel.Text = value;
       }
    }
    

    Then you can customize the label's visibility and other properties with the getters/setters.

    0 讨论(0)
提交回复
热议问题