c# - 如何在winform上绘制矩阵
问题描述
我有一个空类 Box,我在下面制作了一个像你这样的矩阵,我想在 winform 上绘制这个矩阵我该怎么做?
例如,如果Box[i,j]
有红色并且我像这样更改框的颜色,那么Box[i.j].color = Color.Black
我的 winform 是否应该Box[i,j]
在绘制整个矩阵后将颜色更改为黑色。
Box[,] boxes = new Box[100, 100];
MainForm form;
Timer timer;
public Game()
{
form = new MainForm();
timer = new Timer();
}
public void Run(int size)
{
form.Paint += new PaintEventHandler(Draw);
timer.Tick += new EventHandler(TimerEventHandler);
timer.Interval = 1000 / 25;
timer.Start();
form.Visible = true;
}
private void TimerEventHandler(Object obj, EventArgs args)
{
form.Refresh();
}
private void Draw(Object obj, PaintEventArgs args)
{
}
解决方案
这是一种方法(不是唯一的方法):
首先,给出Box
一个将自身绘制到 Graphics 上下文的方法:
class Box
{
public Color color { get; set; } = Color.Red;
// Note: Conventionally, property names begin with a capital letter.
/// <summary>
/// Draw this block to the given graphics context.
/// </summary>
/// <param name="g">The graphics context to draw to.</param>
/// <param name="x">X-coordinate of the block within the graphics context.</param>
/// <param name="y">Y-coordinate of the block within the graphics context.</param>
/// <param name="width">Width of the area in which to draw the block.</param>
/// <param name="height">Height of the area in which to draw the block.</param>
public void DrawTo(Graphics g, int x, int y, int width, int height)
{
// Fill in the color of this block:
Brush brush = new SolidBrush(color); // fill style, color etc.
g.FillRectangle(brush, x, y, width, height);
// Black outline:
Pen pen = new Pen(Color.Black); // line style, color, etc.
g.DrawRectangle(pen, x, y, width, height);
// look up the documentation of the System.Drawing.Graphics class for other methods for drawing.
}
}
现在,如果您想将矩阵绘制为位图图像,您可以这样做:
private void DrawMatrix(System.Drawing.Bitmap bm)
{
Graphics g = Graphics.FromImage(bm);
try
{
for (int y = 0; y < MatrixHeight; y++)
for (int x = 0; x < MatrixWidth; x++)
{
boxes[x, y].DrawTo(g, x * CellWidth, y * CellHeight, CellWidth, CellHeight);
}
}
finally
{
g.Dispose();
}
}
// Size of the matrix:
const int MatrixWidth = 100;
const int MatrixHeight = 100;
// Size of each cell in pixels:
const int CellWidth = 20;
const int CellHeight = 20;
但这对于每帧都太慢了(对于 100x100 矩阵)。如果您在更改单个单元格时只更新它们,则可以像这样更新屏幕外图像。
然后,您可以PictureBox
在窗体上放置一个控件,并将其Image
属性设置为此处更新的位图。您可以使用创建该位图(此方法的参数)new Bitmap(MatrixWidth * CellWidth, MatrixHeight * CellHeight)
。
或者,您可以在 OnPaint 事件处理程序(Draw
您问题中的方法)中绘制表单的画布。假设窗口滚动(并且并非所有矩阵在任何时候都在视口中可见),您将仅循环通过可见单元格并使它们自己绘制到表单的 Graphics 上下文中。
表单的 Graphics 上下文是Graphics
事件参数对象的属性。这就是上述Box.Draw
方法所需要的。绘制每个单元格时,您必须考虑其在网格中的位置以及窗口的滚动方式,以便计算要传递给该方法的坐标。
每次调用 OnPaint 事件时,只需重绘窗口的一部分。这部分由属性给出ClipRectangle
。(Windows 将要重绘的区域分解为一个或多个矩形,并对每个矩形进行调用。)(ClipRectangle
可能是整个窗口。)允许在此范围之外进行绘制,但可能效率低下。
因此,为了提高效率,您应该只遍历至少部分落在 内的所有单元格ClipRectangle
,计算它们在可见区域内的位置并调用它们的Box.Draw
.
该类使用的坐标Graphics
是可见坐标,因此 (0,0) 是窗口的左上角,与滚动无关。
查看滚动位置的这些属性:
Form.HorizontalScroll.Value
Form.VerticalScroll.Value
推荐阅读
- c# - 在 UserControl WPF 中动态绑定情节提要的持续时间
- python - 如何制作一个简单的利息计算器
- ckfinder - CkFinder 每次都重新创建缩略图
- python - 符号积分返回垃圾
- python - Pytorch 函数调用
- python - 无法将更新的工作表写回同一工作簿-Python Excel Openpyxl
- react-native - javascript 混淆器中的排除参数不起作用
- java - 如何使用 Java Comparator 对数组进行排序?
- java - 如何在java中读取.txt文件直到EOF并正确存储到数组中
- python - 如何将包含数据集的 excel 文件保存到 csv 文件中,同时将值的数据类型保留为浮点数?