动态创建的PictureBox渲染问题
Dynamically created PictureBox rendering problem
最终目标是一个有点可玩的记忆游戏。目前,我陷入了渲染问题。我有以下 类:
字段,这是一个抽象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
循环中,我试图生成一个 6x10 的 Field
网格(每个网格包含一个 PictureBox
100x100 像素的大小)。我这样做几乎成功了,因为我的第二个字段没有正确呈现:
我发现唯一可行的(完全解决了问题)是使字段更大(即 150 像素)。另一方面,将其变小(即 50px)会使问题变得更大:
也许有用的信息和我试过的东西:
- 我的 MainForm 是
AutoSize = true;
和 AutoSizeMode = GrowAndShrink;
- 我的 MainForm(最初)不包含任何组件,除了
menuStrip
和 label
- 我尝试更改
PictureBox.Image
属性,但 没有 工作。
- 我尝试仅使用
PictureBox
控件创建网格(不使用 Field
作为 PictureBox
包装器), 确实 有效。
- 我尝试将
labelTimer
放在那个 "problematic area" 中, 确实 解决了这个问题,具体取决于我把它放在哪里。 (因为字段定位取决于labelTimer
的位置和高度)
- 我尝试重新启动 visual studio 2017,没有 工作。
当然,我可以将大小更改为 150px 然后继续,但我真的很想知道这个问题的根源是什么。谢谢!
解决问题最简单的方法是您已经尝试过的方法 - 直接使用 PictureBox
而不是 Field
。现在,考虑到您只使用 Field
来包装 PictureBox
,您可以继承 PictureBox
而不是仅仅包装它。
将您的 类 更改为这些将解决您注意到的问题:
public abstract class Field : PictureBox {
public Field() {
Image = Image.FromFile(@"Bomb01.jpg");
SizeMode = PictureBoxSizeMode.StretchImage;
BorderStyle = BorderStyle.FixedSingle;
Size = new Size(100, 100);
}
// ...
// some abstract methods, not currently important
}
public class MemoryField : Field {
public MemoryField(Form parent, int xPos, int yPos, int xSize, int ySize) {
ClientSize = new Size(xSize, ySize);
Location = new Point(xPos, yPos);
}
// ...
}
它不起作用的真正原因与每个 Field
及其子组件的 sizing 和 positioning 有关.您不应相对于其父级 MemoryField
设置每个 _pictureBox
的 Location
,而是相对于其父级 [=24] 更改 MemoryField
的 Location
=].
您还应该将 MemoryField
的大小设置为其子项 _pictureBox
的大小,否则它将无法正确调整以适合其内容。
public class MemoryField : Field {
public MemoryField(Form parent, int xSize, int ySize) {
_pictureBox.ClientSize = new Size(xSize, ySize);
// I removed the setting of Location for the _pictureBox.
this.Size = _pictureBox.ClientSize; // size container to its wrapped PictureBox
this.Parent = parent; // not needed
}
// ...
}
并将您的创建内循环更改为
for (int x = 0; x < 10; x++) // 10 columns
{
Field field = new MemoryField(this,
fieldWidth,
fieldHeight);
field.Location = new Point(x * (fieldWidth + 3), 0 + 0 + y * (fieldHeight + 3)); // Set the Location here instead!
this.Controls.Add(field);
}
最终目标是一个有点可玩的记忆游戏。目前,我陷入了渲染问题。我有以下 类:
字段,这是一个抽象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
循环中,我试图生成一个 6x10 的 Field
网格(每个网格包含一个 PictureBox
100x100 像素的大小)。我这样做几乎成功了,因为我的第二个字段没有正确呈现:
我发现唯一可行的(完全解决了问题)是使字段更大(即 150 像素)。另一方面,将其变小(即 50px)会使问题变得更大:
也许有用的信息和我试过的东西:
- 我的 MainForm 是
AutoSize = true;
和AutoSizeMode = GrowAndShrink;
- 我的 MainForm(最初)不包含任何组件,除了
menuStrip
和label
- 我尝试更改
PictureBox.Image
属性,但 没有 工作。 - 我尝试仅使用
PictureBox
控件创建网格(不使用Field
作为PictureBox
包装器), 确实 有效。 - 我尝试将
labelTimer
放在那个 "problematic area" 中, 确实 解决了这个问题,具体取决于我把它放在哪里。 (因为字段定位取决于labelTimer
的位置和高度) - 我尝试重新启动 visual studio 2017,没有 工作。
当然,我可以将大小更改为 150px 然后继续,但我真的很想知道这个问题的根源是什么。谢谢!
解决问题最简单的方法是您已经尝试过的方法 - 直接使用 PictureBox
而不是 Field
。现在,考虑到您只使用 Field
来包装 PictureBox
,您可以继承 PictureBox
而不是仅仅包装它。
将您的 类 更改为这些将解决您注意到的问题:
public abstract class Field : PictureBox {
public Field() {
Image = Image.FromFile(@"Bomb01.jpg");
SizeMode = PictureBoxSizeMode.StretchImage;
BorderStyle = BorderStyle.FixedSingle;
Size = new Size(100, 100);
}
// ...
// some abstract methods, not currently important
}
public class MemoryField : Field {
public MemoryField(Form parent, int xPos, int yPos, int xSize, int ySize) {
ClientSize = new Size(xSize, ySize);
Location = new Point(xPos, yPos);
}
// ...
}
它不起作用的真正原因与每个 Field
及其子组件的 sizing 和 positioning 有关.您不应相对于其父级 MemoryField
设置每个 _pictureBox
的 Location
,而是相对于其父级 [=24] 更改 MemoryField
的 Location
=].
您还应该将 MemoryField
的大小设置为其子项 _pictureBox
的大小,否则它将无法正确调整以适合其内容。
public class MemoryField : Field {
public MemoryField(Form parent, int xSize, int ySize) {
_pictureBox.ClientSize = new Size(xSize, ySize);
// I removed the setting of Location for the _pictureBox.
this.Size = _pictureBox.ClientSize; // size container to its wrapped PictureBox
this.Parent = parent; // not needed
}
// ...
}
并将您的创建内循环更改为
for (int x = 0; x < 10; x++) // 10 columns
{
Field field = new MemoryField(this,
fieldWidth,
fieldHeight);
field.Location = new Point(x * (fieldWidth + 3), 0 + 0 + y * (fieldHeight + 3)); // Set the Location here instead!
this.Controls.Add(field);
}