数组中可以有不同颜色的矩形吗?

时间:2019-05-03 01:15:04

标签: c# winforms

我才刚开始使用C#,并且已经开始创建Windows Form Paint应用程序。我遇到的一个问题是,我找不到一种将矩形数组(Rectangle[] rect)中的矩形设置为不同颜色的方法。我显然可以将所有矩形设置为单一颜色,但是我希望能够选择保留已放置的矩形的颜色。

我知道为什么会发生此问题,这是因为在绘画功能中,我正在遍历索引并使用e.Graphics.FillRectangle并将其分配给一种颜色。在保持矩形原始颜色的同时,有其他更好的方法吗?

paint函数中的实际for循环:

for (int i = rect.Length - 1; i > 0; i--)
     e.Graphics.FillRectangle(blockBrush, rect[i]);

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

如评论中所述,您可以为矩形引入一个简单的数据结构,以表示要渲染的对象。例如,我们称它们为Tile。瓷砖将由矩形矩形和颜色组成。

public class Tile
{
    public Rectangle Rect { get; set; }
    public Color? Color { get; set; } = null;
}

我使颜色可以为空,以区分具有颜色集的矩形和没有颜色集的矩形。

我们的代码将代替List<Rectangle>()Rectangle[]处理List<Tile>()

因此,在一种情况下,我们要设置当前没有颜色设置的所有图块的颜色,然后渲染它们:

var tilesToRender = allTiles.Where(x => !x.Color.HasValue).ToList();
Color newColor = Color.FromName("Red"); // However you source the color to use...
using(var brush = new SolidBrush(newColor))
{
    foreach(var tile in tilesToRender)
    {
        tile.Color = newColor;
        e.Graphics.FillRectangle(brush, tile.Rect); // or appropriate paint method...
    }
}

重要的一点:我们使用Linq和Where查找所有未设置颜色的图块,然后仅对这些颜色进行迭代以设置这些图块颜色并绘制这些矩形。

如果我们只想设置这些颜色并绘制所有矩形:

var tilesToRender = allTiles.Where(x => !x.Color.HasValue).ToList();
Color newColor = Color.FromName("Red"); // However you source the color to use...
using(var brush = new SolidBrush(newColor))
{
    foreach(var tile in tilesToRender)
    {
        tile.Color = newColor;
        e.Graphics.FillRectangle(brush, tile.Rect); // or appropriate paint method...
    }
}
var otherTiles = allTiles.Except(tilesToRender).GroupBy(x => x.Color).ToList();
foreach(var colorGroup in otherTiles)
{
    Color color = colorGroup.Key;
    using(var brush = new SolidBrush(color))
    {
        foreach(var tile in tilesToRender)
        {
            e.Graphics.FillRectangle(brush, tile.Rect); // or appropriate paint method...
        }
    }
}

这将设置所有新图块的颜色并进行渲染,然后获取剩余的已有图块并已具有颜色的图块,将它们按颜色分组并进行渲染。分组是一种优化,因此我们只需为每种颜色设置一次画笔并渲染该颜色的所有矩形,然后继续使用下一个颜色。 (而不是可能在矩形之间来回切换颜色)

请注意,画笔的使用是通过using()块完成的。这是因为刷子是一次性的,应在使用后丢弃。因此,我们将画笔的寿命范围限定在需要的地方,并将其放置在using()块的末尾。

因此,现在您可以使用代码/控件将新的Tiles添加到具有Rect但没有颜色设置的AllTiles集合中,并且可以调用该方法以查找缺少颜色的任何新Tiles,设置颜色并渲染这些瓷砖。

希望它概述了有关如何使用对象来跟踪对象状态以及从那里可以前往的状态的一些想法。