首页 > 解决方案 > 为什么按钮会闪烁?

问题描述

当我进入主按钮时,我将 2 个按钮(从现在开始的自定义按钮)添加到按钮的控件(从现在开始的主按钮)中,我希望自定义按钮出现 ImageBackground,它可以正常工作。现在,当我用鼠标进入自定义按钮时,我希望 2 ImageBackground 再次出现,当发生这种情况时,我希望主按钮保持与我第一次用鼠标输入时相同的颜色,这发生在我想要它,但按钮闪烁,有时当我输入另一个主按钮的自定义按钮时,前一个按钮仍处于 mouseEnter 状态。这是为什么?我需要使用 async/await 或类似的东西吗?

我想可能是因为它必须在它发生时进行编译,这需要一点时间,这就是它闪烁的原因,这就是我认为我需要使用 async/await 的原因,但这对我来说真的很新,所以我不不知道怎么用。

public class MyButton : Button
    {
        public MyButton()
        {
            SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick | ControlStyles.UserMouse, true);

            Margin = new Padding(0);
            TextAlign = ContentAlignment.TopCenter;
            ImageAlign = ContentAlignment.TopLeft;
            TextImageRelation = TextImageRelation.ImageBeforeText;
            Font = new Font("Century Gothic", 11f, FontStyle.Bold);
            Size = new Size(200, 75);
            FlatStyle = FlatStyle.Flat;
            BackColor = Color.FromArgb(0, 255, 255, 255);
            FlatAppearance.MouseOverBackColor = ColorTranslator.FromHtml("#64A4B3B6");
            FlatAppearance.BorderSize = 2;
            FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);

            Button[] custom = CustomButtons();
            for (int i = 0; i < 2; i++)
            {
                Controls.Add(custom[i]);
                Controls[i].MouseHover += CustomOnMouseEnter;
            }

            MouseEnter += OnMouseEnter;
            MouseLeave += OnMouseLeave;
        }

        private Button[] CustomButtons()
        {

            Button delete = new Button();
            delete.Name = "delete";
            delete.Location = new Point(this.Size.Width - 22, 2);
            delete.Size = new Size(20, 20);
            delete.FlatStyle = FlatStyle.Flat;
            delete.BackColor = Color.Transparent;
            delete.FlatAppearance.MouseOverBackColor = ColorTranslator.FromHtml("#64A4B3B6");
            delete.FlatAppearance.BorderSize = 0;

            Button customize = new Button();
            customize.Name = "customize";
            customize.Location = new Point(delete.Left - 20, delete.Top);
            customize.Size = new Size(20, 20);
            customize.FlatStyle = FlatStyle.Flat;
            customize.BackColor = Color.Transparent;
            customize.FlatAppearance.MouseOverBackColor = ColorTranslator.FromHtml("#64A4B3B6");
            customize.FlatAppearance.BorderSize = 0;

            Button[] buttons = { delete, customize };
            return buttons;
        }

        private void OnMouseLeave(object sender, EventArgs e)
        {
            if (Controls.Count != 0)
            {
                Controls[0].BackgroundImage = null;
                Controls[1].BackgroundImage = null;
            }

            if (BackColor != ColorTranslator.FromHtml("#64389eed"))
            {
                BackColor = Color.FromArgb(0, 255, 255, 255);
            }
        }

        private void OnMouseEnter(object sender, EventArgs e)
        {
            if (Controls.Count != 0)
            {
                Controls[0].BackgroundImage = Resources.cross;
                Controls[1].BackgroundImage = Resources.settings;
            }
        }

        private void CustomOnMouseEnter(object sender, EventArgs e)
        {
            this.BackColor = ColorTranslator.FromHtml("#64A4B3B6");
            Controls[0].BackgroundImage = Resources.cross;
            Controls[1].BackgroundImage = Resources.settings;
        }
    }

这是此代码的输出,输出 当我输入自定义按钮时,您可以看到闪烁,并且即使我离开了,前一个按钮仍处于 MouseEnter 状态!

非常感谢您的每一次帮助!

标签: c#winformsbuttoncontrols

解决方案


主要问题是“OnMouseLeave”不仅在鼠标离开整个控件时被调用,而且在它进入两个小按钮中的任何一个时都会被调用,因为它们与它们的父级重叠。您还应该使用“MouseEnter”事件而不是“MouseHover”。

下面你会发现一个有点简化的版本,应该可以解决问题。“内部”字段包含关于整个控件的“进入”数减去“离开”数。如果它的值大于零,则鼠标在控件内部,包括两个小按钮。

public class MyButton : Button
{
    Image[] images;
    Button[] custom;
    Color hilited = ColorTranslator.FromHtml("#64A4B3B6");
    int inside;

    public MyButton()
    {
        SetStyle(ControlStyles.StandardClick | ControlStyles.StandardDoubleClick | ControlStyles.UserMouse, true);

        Margin = new Padding(0);
        TextAlign = ContentAlignment.TopCenter;
        ImageAlign = ContentAlignment.TopLeft;
        TextImageRelation = TextImageRelation.ImageBeforeText;
        Font = new Font("Century Gothic", 11f, FontStyle.Bold);
        Size = new Size(200, 75);
        FlatStyle = FlatStyle.Flat;
        BackColor = Color.Transparent;
        FlatAppearance.MouseOverBackColor = hilited;
        FlatAppearance.BorderSize = 2;
        FlatAppearance.BorderColor = Color.FromArgb(0, 255, 255, 255);

        images = new Image[] { Resources.cross, Resources.settings };
        custom = CustomButtons();
        for (int i = 0; i < 2; i++)
        {
            Controls.Add(custom[i]);
            Controls[i].MouseEnter += CommonEnter;
            Controls[i].MouseLeave += CommonLeave;
        }

        MouseEnter += CommonEnter;
        MouseLeave += CommonLeave;
    }

    private Button[] CustomButtons()
    {
        Button delete = new Button();
        delete.Name = "delete";
        delete.Location = new Point(this.Size.Width - 22, 2);
        delete.Size = new Size(20, 20);
        delete.FlatStyle = FlatStyle.Flat;
        delete.BackColor = Color.Transparent;
        delete.FlatAppearance.MouseOverBackColor = hilited;
        delete.FlatAppearance.BorderSize = 0;

        Button customize = new Button();
        customize.Name = "customize";
        customize.Location = new Point(delete.Left - 20, delete.Top);
        customize.Size = new Size(20, 20);
        customize.FlatStyle = FlatStyle.Flat;
        customize.BackColor = Color.Transparent;
        customize.FlatAppearance.MouseOverBackColor = hilited;
        customize.FlatAppearance.BorderSize = 0;

        return new Button[] { delete, customize };
    }

    void CommonEnter(object sender, EventArgs e)
    {
        if (inside++ == 0)
        {
            BackColor = hilited;
            custom[0].BackgroundImage = images[0];
            custom[1].BackgroundImage = images[1];
        }
    }

    void CommonLeave(object sender, EventArgs e)
    {
        if (--inside == 0)
        {
            BackColor = Color.Transparent;
            custom[0].BackgroundImage = null;
            custom[1].BackgroundImage = null;
        }
    }
}

推荐阅读