Можно ли иметь разные цветные прямоугольники в массиве? - PullRequest
0 голосов
/ 03 мая 2019

Я только начинаю в C #, и я начал создавать приложение для рисования формы Windows. Одна проблема, с которой я столкнулся, заключается в том, что я не могу найти способ установить прямоугольники в моем массиве прямоугольников (Rectangle[] rect) на разные цвета. Я могу явно установить все прямоугольники в единый цвет, но я бы хотел иметь возможность сохранить цвета уже размещенных прямоугольников.

Я знаю, почему возникает эта проблема, и это потому, что в функции рисования я перебираю индекс и использую e.Graphics.FillRectangle и присваиваю его одному цвету. Есть ли другой / лучший способ сделать это, сохраняя оригинальный цвет прямоугольников?

Фактический цикл for в функции рисования:

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

Я бы очень признателен за любую помощь.

1 Ответ

2 голосов
/ 03 мая 2019

Как уже упоминалось в комментариях, вы можете представить простую структуру данных для ваших прямоугольников, чтобы представить объекты, которые вы визуализируете. Например, давайте назовем их плиткой. Плитки будут состоять из Rect для их прямоугольной области и цвета.

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().

Так что теперь вы можете иметь код / ​​элементы управления, которые добавляют новые плитки в коллекцию AllTiles с Rect, но без установленного цвета, и могут вызывать метод для поиска любых новых плиток, не имеющих цвета, установки цвета и их рендеринга. плитка.

Надеюсь, в нем изложены некоторые идеи о том, как использовать объект для отслеживания состояния вашего объекта и куда вы можете отправиться оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...