2012-01-25 2 views
2

WinForm 그래픽 지식을 얻고 싶습니다. 따라서 XNA의 작은 2D 편집기를 WinForm Graphics 전용으로 다시 작성하고 있습니다.Winform을 사용한 드로잉

이제 저는 타일셋에 대한 새로운 UserControl을 만들었지 만, 내가 보았 듯이 Paint 메서드는 컨트롤 초기화시에만 호출됩니다. 내 컨트롤을 영구적으로 다시 그리기 (또는 적어도 성능을 저장하기 위해 MouseOver 이벤트를 통해), 나는 Invalidate() 메서드가 컨트롤을 다시 그릴 수 있다고 들었지만 way도 성능이 좋지 않습니다.

이러한 성능 문제가없는 코드를 통해 내 UserControl 자체를 페인트 할 수있는 방법이 있습니까?

답변

3

방법은 이 아니며은 컨트롤의 초기화에서만 호출됩니다. 컨트롤을 다시 칠해야 할 때마다 호출됩니다. 이것은 물론 컨트롤이 처음 생성 될 때 발생합니다. 또한 응용 프로그램이 최소화 된 다음 복원되고, 다른 창이 응용 프로그램 위로 이동되어 해당 내용을 가리고 제거 된 경우에도 발생합니다. Invalidate 메서드 또는 동등 물을 사용하여 컨트롤의 클라이언트 영역을 무효화 할 때도 발생합니다. 이는 성능 최적화로서 Windows 개발 초기에 이루어 졌으므로 변경되지 않은 것을 다시 칠할 필요가 없습니다!

강제로 컨트롤을 다시 칠하려면 Invalidate method을 호출하고 클라이언트 영역의 특정 영역을 다시 칠하도록 지정해야합니다.

"way 너무 부적절합니다"에 대해 무슨 뜻인지 전혀 모르겠다. Invalidate 메서드가 느려지는 것은 불가능합니다. 모든 작업은 Windows가 유휴 상태 일 때마다 (즉, 다른 메시지를 처리하지 않음) Windows를 다시 그려야한다고 알려주는 플래그를 설정합니다.

당신이 컨트롤을 다시 칠하도록 Windows를 강제 할 경우 즉시 (가 유휴 상태가 될 때까지 기다리지 않고, 초기부터 윈도우에 내장 된 다른 성능 최적화)를 모두 무효화하는 즉시 다시 그리기를 강제로 Update method를 호출 지역.

Paint 이벤트 처리기 메서드 내에서 그림 코드가 느린 경우에만 느려질 수 있습니다. 그리고 분명히 그것을 보지 않고 코드를 최적화하는 방법을 말할 수는 없습니다.


는 이러한 성능 문제가 발생하지 않고 내 UserControl을이 코드를 통해 자신을 그릴 수 있도록 어쨌든이 있나요?

Paint 이벤트는 컨트롤이 어떻게 그리고 어디에서 스스로를 페인트해야하는지입니다. 그것이 그곳에있는 이유입니다.

당신은 당신이 컨트롤이 앞서 언급 한 바와 같이 예상 예기치의, 임의의 숫자에 대한 응답으로 발생할 수있는 (다시 칠하고있는 다음 번에 삭제됩니다 페인트하지Paint 경우에 페인트, 아무것도 할 경우 발생).

때로는 임시 개체를 컨트롤의 클라이언트 영역에 그려야합니다 (예 : MouseDown 이벤트에 대한 응답으로 끌기 사각형 표시).이 경우 Graphics 클래스 (일반적으로 Paint 이벤트 처리기 메서드의 인수로 전달되며 드로잉을 수행 할 메서드를 호출하는 클래스) 인스턴스를 언제든지 얻을 수 있습니다. 컨트롤에 CreateGraphics method을 호출하면 Graphics 개체가 반환됩니다. 그런 다음 Paint 이벤트 처리기 메서드 내부에서와 마찬가지로 얻은 Graphics 개체를 그립니다. 분명히

(즉 범인 사실 인 경우)이/어떤 빨리 Paint 이벤트 처리기 메서드의 내부 도면 코드보다하지 않습니다 수는 없지만, 화면의 원인이됩니다 오히려 즉시를 업데이트 할 컨트롤이 유휴 상태이고 다른 메시지를 처리하지 않을 때보 다. 당신이 컨트롤이 다시 그려 그 다음 번에 삭제됩니다 그리는 모든으로

나는,이 방법은 즉시 제공 을 사용 일시적 피드백되어야한다는 것을 다시 반복합니다. 그런 일이 발생하면 Paint 이벤트가 발생하고 해당 메서드 처리기 내부의 코드가 실행됩니다. 이는 다른 일회용으로 작성한 항목에 대해서는 알지 못합니다. 그렇기 때문에 모든 것이 Paint 이벤트 처리기 메서드 내부에서 발생해야하며 다른 이벤트가 다시 칠할 필요가있을 때 Invalidate (보통은 아니지만 보통 Update)으로 호출해야합니다.

+0

우선 - 답변 해 주셔서 감사합니다. 음, 아마도 성능 문제는 아니지만 MouseMove-Method가 컨트롤이 다시 칠하기를 기다리는 시간입니까? 내 컨트롤에는 ScrollY-Variable이 있는데, 그래픽의 위치를 ​​조정하고 그 옆에있는 vScrollbar로 조정해야합니다. 그래서 나는 ScrollY-value를 업데이트하고 스크롤바의 Invalidate-Method를 호출하는 vScrollbar_Scroll-Event를 가지고 있습니다. 그러나 그것은 매우 느립니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? –

+0

자, 조언 해 주신 덕분에 조금 더 조사하고 문제를 해결했습니다. ControlStyles.AllPaintingInWmPaint 및 ControlStyles.OptimizedDoubleBuffer 플래그를 true로 설정하고 내 그림 영역을 줄이고 모든 작업을 매우 원활하게 처리했습니다. 감사! –

+1

@ 할아버지 : 음, 그래. 이중 버퍼링은 UI 업데이트를 부드럽게하는 표준 방법입니다. 일반적으로 깜박임에 대한 응답으로 표시되며, 느린 것으로 설명하지 않았습니다. 'AllPaintingInWmPaint'는'WM_ERASEBKGND' 메세지를 처리하고 기본 색상을 페인트함으로써 컨트롤이 먼저 지우지 않는다는 것을 의미합니다. 이중 버퍼링은 WinForms에서 제공됩니다. 그것은 모든 것을 처음에 오프 스크린 버퍼로 끌어 온 다음, 오프 스크린 버퍼를 화면에 직접 블릿합니다. 모든 중간 색칠 단계가 그 길을 따라 진행되는 것을 보지 못하기 때문에 이것은 도움이됩니다. –

관련 문제