为什么按钮会闪烁?
Why does the button flicker?
当我进入主按钮时,我有 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 状态的方式,即使我离开了它!
非常感谢您的帮助!
主要问题是 "OnMouseLeave" 不仅在鼠标离开整个控件时被调用,而且在鼠标进入两个小按钮中的任何一个时也会被调用,因为它们与父按钮重叠。您还应该使用 "MouseEnter" 事件而不是 "MouseHover".
您会在下面找到一个应该可以解决问题的稍微简化的版本。 "inside" 字段包含 "enters" 的数量减去整个控件的 "leaves" 的数量。如果它的值大于零,则鼠标在控件内,包括两个小按钮。
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;
}
}
}
当我进入主按钮时,我有 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;
}
}
这是这段代码的输出
非常感谢您的帮助!
主要问题是 "OnMouseLeave" 不仅在鼠标离开整个控件时被调用,而且在鼠标进入两个小按钮中的任何一个时也会被调用,因为它们与父按钮重叠。您还应该使用 "MouseEnter" 事件而不是 "MouseHover".
您会在下面找到一个应该可以解决问题的稍微简化的版本。 "inside" 字段包含 "enters" 的数量减去整个控件的 "leaves" 的数量。如果它的值大于零,则鼠标在控件内,包括两个小按钮。
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;
}
}
}