向 C# winforms 控件添加徽章

Oxy*_*ron 2 .net c# winforms

用 CSS 编写时,我可以添加一类“徽章”并获得我想要的。按钮或选项卡附近的一个小数字,带有一些样式,以表明此控件具有需要审查的待处理信息。

甚至有一个帖子在这里,在有人试图做我想做的iOS上的

我想在 WinForms 上的按钮或选项卡上执行此操作。如果 WPF 中有更简单的解决方案,那么我可能会考虑使用它。

这是一张图像,显示了我想要实现的目标:

带有徽章的按钮和控件

TaW*_*TaW 6

这是一种使用静态 Adorner 类的方法,非常快速且相当脏。

它可以为许多控件添加一个标签,它包括一个点击动作、动态文本和删除标签的代码。

一个装饰按钮

将徽章添加到按钮需要一行:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

这是 Adorner 类:

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);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,虽然您可以将其添加到大多数控件中,但并非所有控件都像Button. ATabControl很难装饰,因为它Tabs实际上Controls不仅仅是涂漆的区域,所以就像在它上面添加一个“接近的 X”一样,你必须user draw在所有TabPages..