2014-10-24 3 views
0

мне нужно рисовать прямоугольники в Winform что-то вроде этого изображения:Как нарисовать прямоугольники последовательно в СТГ, как петли в Winform

enter image description here

Я также должен быть более ясным. Я хочу достичь этого сценария: предположим, что есть текст в форме «ABCDEFG». Когда пользователь нажимает букву B, я хочу добавить фона прямоугольника с цветом (выделить) на эту букву и последовательные 3 буквы (в этом случае, Я хочу выделить BCD).

В методе я попытался это:

for (int i = 0; i < 5; i++) 
{ 
    letterArea = new Rectangle(rectStartX, rectStartY, (int)Math.Ceiling(charSize.Width), (int)Math.Ceiling(charSize.Height)); 
    rectStartX += (int)Math.Ceiling(charSize.Width); 
} 

Слово Invalidate() в конце этого метода. В OnPaintBackGround у меня есть следующие строки:

Rectangle rectContent = vsr.GetBackgroundContentRectangle(e.Graphics, this.ClientRectangle); 
e.Graphics.FillRectangle(new SolidBrush(Color.Red), letterArea); 

где letterArea - поле класса. Я прочитал в другом вопросе, что вызов Invalidate() в цикле не гарантирует вызов OnPaintBackground. Мне не интересно вычислять координаты, вместо этого меня интересует, какой метод я должен нарисовать прямоугольники и где вызвать Invalidate() и что является эффективным решением? Спасибо, заранее.

+0

* Invalidate * отправляет красное сообщение в окно. Краска посылает соответственно * erasebackground *. Отправка одного или 1000 недействительных в цикле ничего не меняет. В конце будет отправлено только одно сообщение с краской. Общепринятой практикой является рисование * paint * –

+0

_calling Invalidate() в цикле не гарантирует вызов OnPaintBackground._ Да, это так. Может быть, не сразу и не чаще, чем необходимо, но вы можете смело полагаться на контроль, который будет дергаться. – TaW

+1

В вашем методе вы создаете несколько Rectangles, но вы ничего не делаете с ними? Если вы добавите их в список классов , ваше событие рисования может использовать его для заполнения каждого из них. – TaW

ответ

0

Вы должны нарисовать свои прямоугольники в методе OnPaint, а в OnPaintBackground.

Также обратите внимание, что вызов Invalidate() не вызывает синхронной краски. Чтобы заставить синхронную краску, вызовите Update() после вызова Invalidate() или используйте Refresh(), который делает то же самое, что и Invalidate + Update (но также влияет на дочерние элементы управления). См. MSDN для справки.

+0

Andy Я обновил свой вопрос, чтобы быть более ясным. Является ли рисование в OnPaint еще истинным, когда я хочу выделить фон некоторых букв? Благодарю. –

+1

В коде Forms вы всегда должны рисовать 'OnPaint()'. Вам необходимо поддерживать структуры данных, которые описывают ваш внешний вид (например, список прямоугольников, выделение текста и т. Д.), Вызывать 'Invalidate()' когда какая-либо из этих данных изменяется, а затем нарисовать правильный внешний вид, когда 'OnPaint () '. Также обратите внимание, что хотя .NET предоставляет синхронный API-интерфейс, практически никогда не стоит его использовать. Ожидание сообщения WM_PAINT (что и вызывает вызов OnPaint() ') и перерисовка, это обычный и правильный подход. –

Смежные вопросы