gpt4 book ai didi

c# - Foreach 循环创建 100 个按钮,同时绘制所有按钮以防止闪烁

转载 作者:行者123 更新时间:2023-11-30 13:48:14 24 4
gpt4 key购买 nike

在我的扫雷游戏中,我需要动态创建控件以便在简单 - 中等 - 困难之间切换。假设这个问题的难点由 100 个按钮组成。

这就是我创建它们的方式:

this.SuspendLayout(); //Creating so many things that I assume it would be faster to suspend and resume.
foreach (string i in playingField)
{

Button button = new Button();
button.Name = i;
button.FlatStyle = System.Windows.Forms.FlatStyle.Popup;
button.Margin = new Padding(0);
button.TabIndex = 0;
button.Location = new System.Drawing.Point(3, 3);
button.Size = new System.Drawing.Size(25, 25);
button.BackgroundImage = blockImage; //##//
button.MouseDown += new System.Windows.Forms.MouseEventHandler(this.GetUnderSide);
button.UseVisualStyleBackColor = false;
minesPanel.Controls.Add(button); //Adding the controls to the container
}
this.ResumeLayout(); //Refer to above. Correct me if I'm wrong please.

如您所见,我正在通过 for 循环创建所有控件,然后添加它们。它导致每个按钮一次被绘制一次。我还尝试了 name.Controls.AddRange(arrayButtons) ,它仍然导致同样的问题。个人绘画。

我需要的是一种方法来创建所有项目,然后将它们全部绘制出来,就像使用 DoubleBuffered 绘制单个位图一样,但遗憾的是,这也不起作用。

另外,我试过这个:

    protected override CreateParams CreateParams
{
get
{
// Activate double buffering at the form level. All child controls will be double buffered as well.
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return cp;
}
}

哪种作品。它仅适用于应用程序启动。但是,考虑到我将在运行时更改网格大小并添加更多控件,这不是一个可行的选择。

有人告诉我这就像使用 Graphics 类中的方法一样简单。问题是,我不知道从哪里开始。

如果有人可以提供一些帮助来同时绘制我的所有控件,那就太好了。

最佳答案

遗憾的是,WinForms 不喜欢拥有太多控件,尤其是当您拥有数百个控件时。您永远无法让每个控件同时绘制,因为每个控件都会将自己的绘制消息发送到窗口。

我认为处理像扫雷这样的游戏板的最佳方法是只使用一个控件并绘制按钮网格。

简单的地雷类:

public class Mine {
public Rectangle Bounds { get; set; }
public bool IsBomb { get; set; }
public bool IsRevealed { get; set; }
}

然后创建一个新控件,在其中继承自 Panel 控件并设置 DoubleBuffered 属性以防止任何闪烁:

public class MineSweeperControl : Panel {
private int columns = 16;
private int rows = 12;
private Mine[,] mines;

public MineSweeperControl() {
this.DoubleBuffered = true;
this.ResizeRedraw = true;

// initialize mine field:
mines = new Mine[columns, rows];
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < columns; ++x) {
mines[x, y] = new Mine();
}
}
}

// adjust each column and row to fit entire client area:
protected override void OnResize(EventArgs e) {
int top = 0;
for (int y = 0; y < rows; ++y) {
int left = 0;
int height = (this.ClientSize.Height - top) / (rows - y);
for (int x = 0; x < columns; ++x) {
int width = (this.ClientSize.Width - left) / (columns - x);
mines[x, y].Bounds = new Rectangle(left, top, width, height);
left += width;
}
top += height;
}
base.OnResize(e);
}

protected override void OnPaint(PaintEventArgs e) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < columns; ++x) {
if (mines[x, y].IsRevealed) {
e.Graphics.FillRectangle(Brushes.DarkGray, mines[x, y].Bounds);
} else {
ControlPaint.DrawButton(e.Graphics, mines[x, y].Bounds,
ButtonState.Normal);
}
}
}
base.OnPaint(e);
}

// determine which button the user pressed:
protected override void OnMouseDown(MouseEventArgs e) {
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < columns; ++x) {
if (mines[x, y].Bounds.Contains(e.Location)) {
mines[x, y].IsRevealed = true;
this.Invalidate();
MessageBox.Show(
string.Format("You pressed on button ({0}, {1})",
x.ToString(), y.ToString())
);
}
}
}
base.OnMouseDown(e);
}
}

enter image description here

关于c# - Foreach 循环创建 100 个按钮,同时绘制所有按钮以防止闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13194674/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com