我有一个C#程序,我正在尝试绘制GUI。此程序是一个2D数组,其中数组中的每个点可以具有不同类型的Space
对象:Asteroid
,EmptySpace
或GravityWell
。
我的SpaceProbeView
类将传递2D数组,然后在表单的每个空间中绘制一个小矩形,具有不同的颜色,具体取决于Space
对象。
我遇到的问题是我的程序实际上没有绘制任何东西。我可以添加一个随机矩形并从Graphics对象中绘制它,但这就是所有绘制的。难道我做错了什么?我是Windows Forms的新手。
以下是SpaceProbeView
类:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections;
namespace SpaceProbe
{
class SpaceProbeView : Form
{
private int squareSize;
public int SquareSize
{
get { return squareSize; }
set { squareSize = value; }
}
private Space[,] map;
public void setMap(Space[,] aMap) { map = aMap; }
private int mapSize;
private int rowSize;
public SpaceProbeView(int numberOfSpaces)
{
mapSize = numberOfSpaces;
rowSize = (int)Math.Sqrt(mapSize);
Size = new System.Drawing.Size(mapSize *5, mapSize * 5);
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics graphics = e.Graphics;
for(int row = 0; row < rowSize; row++)
{
for(int column = 0; column < rowSize; column++)
{
graphics.FillRectangle(map[row, column].getBrush(), row * SquareSize,
column * SquareSize, SquareSize, SquareSize);
}
}
}
}
}
我的Space
界面是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace SpaceProbe
{
public interface Space
{
SolidBrush getBrush();
}
}
使用其中一个Space
子类的代码EmptySpace
(添加所有子类似乎没必要,它们都遵循这种模式):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace SpaceProbe
{
class EmptySpace : Space
{
private static EmptySpace instance = new EmptySpace();
public static EmptySpace Instance
{
get { return instance; }
set { }
}
private SolidBrush brush = new SolidBrush(Color.DeepPink);
public SolidBrush getBrush() { return brush; }
private EmptySpace() { }
}
}
和Map
类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace SpaceProbe
{
class Map
{
private Space[,] map;
public Space[,] TheMap
{
get { return map; }
set { }
}
public Map(int size)
{
map = new Space[size, size];
Random random = new Random();
for (int row = 0; row < size; row++)
{
for (int column = 0; column < size; column++)
{
//TODO: make this so that it enforces the right quantity of each, not just a vague percentage
int randomInt = random.Next(11);
if (randomInt <= 1)
map[row, column] = GravityWell.Instance;
else if (randomInt > 1 && randomInt <= 7)
map[row, column] = EmptySpace.Instance;
else if (randomInt > 7 && randomInt <= 10)
map[row, column] = Asteroid.Instance;
}
}
}
}
}
并且全部运行于:
using System;
using System.Windows.Forms;
namespace SpaceProbe
{
class Program
{
static void Main(string[] args)
{
Map map = new Map(10);
SpaceProbeView view = new SpaceProbeView(100);
view.setMap(map.TheMap);
Application.Run(view);
}
}
}
答案 0 :(得分:1)
这实际上是完整的代码示例吗?如果是这样,那么您的问题是您永远不会初始化SquareSize
属性。由于它是0
,因此您的矩形是空的,因此当您拨打FillRectangle()
时,当然没有任何内容被绘制。
只要我在这里:),我也会推荐一些其他的改变。例如,以下是更惯用的C#(不是类似Java),还包括更好的实现实践:
class EmptySpace : Space
{
private static readonly EmptySpace instance = new EmptySpace();
public static EmptySpace Instance
{
get { return instance; }
}
private static readonly SolidBrush brush = new SolidBrush(Color.DeepPink);
public SolidBrush Brush { get { return brush; } }
private EmptySpace() { }
}
换句话说,当您具有类似属性的语义时,应该使用真实属性。此外,如果永远不应更改字段,请使用readonly
声明该字段(类似于Java中的final
,至少在此上下文中)。最后,您可以将brush
字段设置为静态,因为即使您有多个EmptySpace
实例(我知道,您也不会),所有实例都将共享相同的画笔。< / p>
其他Space
子类也是如此,包括根据需要制作brush
字段readonly
和static
。
我还要注意,持有像Brush
这样的可支配资源的类应该实现IDisposable
。当然,你应该在完成这些课程后处理这些课程的实例。
在SpaceProbeView
课程中:
private Space[,] map;
public void setMap(Space[,] aMap) { map = aMap; }
再次,更好的是:
private Space[,] map;
public Space[,] Map
{
get { return map; } // avoid write-only properties
set { map = value; }
}
因为它用于行和列,所以:
private int mapSize;
private int rowSize;
应该是:
private int mapSize;
private int rowAndColumnSize;
(或类似的东西......只要明确表示它已用于两者)
这段代码,我真的不明白:
public SpaceProbeView(int numberOfSpaces)
{
mapSize = numberOfSpaces;
rowSize = (int)Math.Sqrt(mapSize);
Size = new System.Drawing.Size(mapSize *5, mapSize * 5);
}
我以为我理解了mapSize
和rowSize
的初始化,但后来我看到了Size
的初始化。 5
来自哪里?为什么表单的大小是5x与空格总数一样大,而不仅仅是两个维度(行或列)中的空格数?
根据用法,我会将map
对象传递给构造函数。虽然调用者传递numberOfSpaces
的有效值,但您在此处使用的代码仍可正常工作,但您实际上无法确保它与稍后设置的map
对象的实际尺寸相匹配。 / p>
如果您传递map
对象本身,则可以从该对象中简单地检索行和列维度,甚至不需要调用者传递方形图。在这种情况下,你可能完全摆脱mapSize
变量;目前还不清楚你为什么要这样做。