Моя пользовательская нарисованная графика ретроактивно обрезается, но последующие изменения клипа… как?

#c# #drawing #gdi #clipping #region

#c# #рисование #gdi #обрезка #регион

Вопрос:

Я не понимаю, как это происходит. Вот мой важный код в последовательном порядке:

 protected override void OnPaint(PaintEventArgs e)
{
    g.Clear(backgroundColor);

    CustomCollection.Draw(e.Graphics);
}

// In CustomCollection
public void Draw(Graphics g)
{
    // Here I want to temporarily reset the clip so that I can draw everywhere
    g.ResetClip();
    g.DrawLines(Pens.Red, gridLines);

    foreach (CustomItem item in Items)
    {
        item.Draw(g);
    }
}

// In CustomItem
public void Draw(Graphics g)
{
    GraphicsContainer container = g.BeginContainer();

    // Clip Image to the path
    g.SetClip(path, CombineMode.Intersect);
    g.FillPath(FillBrush, path);
    g.DrawImage(Image, imageRect);
    g.ResetClip();

    g.EndContainer(container);
}
  

Я устанавливаю клип с помощью перегрузки Invalidate (Region). Причина, по которой я это делаю, заключается в том, что у меня много элементов на экране, но часто мне нужно перерисовать только один, поэтому я устанавливаю обрезку до границ этого элемента. Это работает нормально.

Единственное, что я пытаюсь сделать по-другому сейчас, это то, что я хочу рисовать линии сетки, и мне нужно рисовать их каждый раз на всем экране, потому что я выделяю их в зависимости от того, где находится текущий выбранный элемент.

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

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

Когда я комментирую строку item.Draw(g), мои линии сетки больше не обрезаются. Мне кажется, что это ретроактивное обрезание, которое противоречит всему, что я знаю о GDI .

Кто-нибудь, кто может помочь?

Комментарии:

1. PaintEventArgs.ClipRectangle отменяет Graphics.Set / ResetClip().

2. Значит, setClip / ResetClip предназначен только для дальнейшей доработки клипа? Я думаю, что тогда я не смогу делать то, что хочу, не делая недействительными линии сетки при каждом их изменении.