【发布时间】:2020-03-06 10:15:31
【问题描述】:
最终目标是一个有点可玩的记忆游戏。目前,我陷入了渲染问题。我有以下课程:
字段,这是一个抽象的UserControl:
public abstract class Field : UserControl
{
protected PictureBox _pictureBox;
public Field()
{
_pictureBox = new PictureBox();
_pictureBox.Image = Properties.Resources.empty;
_pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
_pictureBox.BorderStyle = BorderStyle.FixedSingle;
this.Controls.Add(_pictureBox);
}
// ...
// some abstract methods, not currently important
}
MemoryField,派生自Field:
public class MemoryField : Field
{
public MemoryField(Form parent, int xPos, int yPos, int xSize, int ySize)
{
_pictureBox.ClientSize = new Size(xSize, ySize);
_pictureBox.Location = new Point(xPos, yPos);
_pictureBox.Parent = parent;
}
// ...
}
最后,MainForm 是我的应用程序的入口点:
public partial class MainForm : Form
{
private readonly int fieldWidth = 100; // 150 no rendering problems at all
private readonly int fieldHeight = 100;
public MainForm() { InitializeComponent(); }
private void MainForm_Load(object sender, EventArgs e)
{
for (int y = 0; y < 6; y++) // 6 rows
{
for (int x = 0; x < 10; x++) // 10 columns
{
Field field = new MemoryField(this,
x * (fieldWidth + 3), // xPos, 3 is for a small space between fields
labelTimer.Location.Y + labelTimer.Height + y * (fieldHeight + 3), // yPos
fieldWidth,
fieldHeight);
this.Controls.Add(field);
}
}
}
}
这是我的问题所在:
在那些for 循环中,我试图生成一个Fields 的6x10 网格(每个都包含PictureBox 100x100 像素大小)。我几乎成功地做到了,因为我的第二个字段没有正确呈现:
我发现唯一有效(完全解决问题)是使字段更大(即 150 像素)。另一方面,将其缩小(即 50px)会使问题变得更大:
也许有用的信息和我尝试过的事情:
- 我的 MainForm 是
AutoSize = true;和AutoSizeMode = GrowAndShrink; - 我的 MainForm(最初)不包含除
menuStrip和label之外的任何组件 - 我尝试更改
PictureBox.Image属性,但没有工作。 - 我尝试仅使用
PictureBox控件创建网格(不使用Field作为PictureBox包装器),确实工作。 - 我尝试将
labelTimer放在那个确实解决问题的“问题区域”中,具体取决于我将它放在哪里。 (因为字段定位取决于labelTimer的位置和高度) - 我尝试重新启动 Visual Studio 2017,没有工作。
当然,我可以将大小更改为 150 像素然后继续,但我真的很想知道这个问题的根源是什么。谢谢!
【问题讨论】:
-
你为什么要这样做:
_pictureBox.Parent = parent;?不要那样做。 PictureBox 应由 UserControl 处理。顺便说一句,UserControl 已经知道它的父级,它是[UC].ParentForm(继承自 ContainerControl)。至少,设置_PictureBox.BringToFront();。但你不应该,真的。 -
我还以为是图片框中的平假名,直到我仔细观察 :) 这可能与您的用户控件无关,它是另一个控件,它隐藏了以较低 z 顺序呈现的部分内容.尝试自下而上,从右到左创建所有内容,以便将其覆盖,或者识别它是什么并将其删除(
labelTimer?)除此之外,考虑派生自PictureBox(子类化)的Field-在您的控制层次结构中减少一层。 -
这里是 IMO 不必要的抽象。将
Pictureboxes 直接放在TableLayoutPanel中即可。 -
未设置 UserControl 的 Size 属性。这是你唯一能看到的,其他的也太大了,但是被 PictureBox 控件重叠了。
-
谢谢大家的建议!确实,主要问题是为
_pictureBox设置大小和位置,而不是为Field设置任何这些(如@hans-passant 所建议并在所选答案中涵盖)。我还删除了.Parent = parent,因为它不需要(@jimi 建议)。现在让我考虑TableLayoutPanel和/或从PictureBox派生Field而不是包装它。再次感谢!
标签: c# .net winforms picturebox