Winforms: Как убыстриться, Делают недействительным ()?

Если вам не нужна ветвь вокруг:

Если вы слили foo обратно в master, «git branch -d foo», чтобы убить ветку темы, а затем "checkout -b foo" в будущем, когда вам снова понадобится взломать его.

Если вам нужна ветвь вокруг:

Вы можете перебазировать свою ветку темы на основную ветвь:

git checkout foo
git rebase master

Или:

git rebase master foo
8
задан Pedery 11 April 2011 в 00:16
поделиться

4 ответа

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

Причина в том, что GDI + ( а также сам GDI) делает недействительными области прямоугольной формы, как вы указываете в ограничивающей рамке. Вы можете убедиться в этом сами, протестировав несколько горизонтальных и вертикальных линий по сравнению с линиями, наклон которых аналогичен аспекту вашей области отображения.

Итак, допустим, ваш холст имеет размер 640x480. Если провести линию от 0,0 до 639,479; Invalidate () сделает недействительным всю область от 0,0 до 639,0 вверху вниз до 0,479 до 639,479 внизу. Горизонтальная линия, скажем, от 0,100 до 639,100 дает прямоугольник высотой всего в 1 пиксель.

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

Итак. В качестве решения, если у вас очень большая линия, разбейте ее на четверти или восьмые, и производительность должна значительно повыситься. Пересматривая приведенный выше пример, если вы просто разделите пополам на две части, вы уменьшите общую недействительную площадь до 0,0 x 319 239 плюс 320 240 x 639 479.

Вот наглядный пример разделения на четверть. Розовая область является недействительной. К сожалению, SO не позволяет мне публиковать изображения или более одной ссылки, но этого должно быть достаточно, чтобы все объяснить.

(Линия разделена на четверти, общая недействительная площадь составляет 1/4 поверхности)

экстент 640x480 с четырьмя прямоугольниками одинакового размера, вырезанными за линией, проведенной по диагонали

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

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

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

8
ответ дан 5 December 2019 в 14:06
поделиться

Чтобы уточнить: рисует ли пользователь прямую линию, или ваша линия на самом деле представляет собой набор сегментов, соединяющих точки мыши? Если линия является прямой линией от начала координат до текущей точки мыши, не используйте Invalidate () и вместо этого используйте кисть XOR, чтобы нарисовать линию, которую нельзя изменить, а затем отрисовать предыдущую линию, только когда пользователь закончит рисовать.

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

1
ответ дан 5 December 2019 в 14:06
поделиться

Как насчет того, чтобы иметь другую ветку, которая «публикует обновления» на реальном холсте.

Image paintImage;
private readonly object paintObject = new object();
public _ctor() { paintImage = new Image(); }

override OnPaint(PaintEventArgs pea) {
    if (needUpdate) {
        new Thread(updateImage).Start();
    }
    lock(paintObject) {
        pea.DrawImage(image, 0, 0, Width, Height);
    }
}

public void updateImage() {
    // don't draw to paintImage directly (it might cause threading issues)
    Image img = new Image();
    using (Graphics g = img.GetGraphics()) {
        foreach (PaintableObject po in renderObjects) {
            g.DrawObject(po);
        }
    }
    lock(paintObject){
        using (Graphics g = paintImage.GetGraphics()) {
            g.DrawImage(img, 0, 0, g.Width, g.Height);
        }
    }
    needUpdate = false;
}

Просто идея, поэтому я не тестировал код; -)

1
ответ дан 5 December 2019 в 14:06
поделиться

Вы не можете действительно ускорить Invalidate. Причина, по которой он работает медленно, заключается в том, что он помещает событие WM_PAINT в очередь сообщений. Затем это фильтруется, и в конечном итоге вызывается ваш OnPaint. Что вам нужно сделать, так это нарисовать прямо в вашем элементе управления во время события MouseMove.

В любом элементе управления, который требует некоторой плавной анимации, мое событие OnPaint обычно вызывает только функцию PaintMe. Таким образом, я могу использовать эту функцию для перерисовки элемента управления в любое время.

2
ответ дан 5 December 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: