Add a badge to a C# winforms control

前端 未结 3 1694
暖寄归人
暖寄归人 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 controls = new List();
    
        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 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 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..

提交回复
热议问题