2009-07-15 2 views
6

완충. 양식의 크기를 조정하면 ListBox가 깜박입니다. 나는 CheckedListBox을 상속하고 (이 기술의 ListView 및 DataGridView를 포함하여 다른 컨트롤로 작동)에 ctor에에 trueDoubleBuffered를 설정했지만, 그것은 아무런 영향을 미치지 않습니다.더블 난 (문제가리스트 박스 인 것을 보여준다 인터넷 검색리스트 박스로부터 상속)을 CheckedListBox (윈폼) 제어를리스트 박스

WS_EX_COMPOSITED 스타일을 CreateParams에 추가하려고 시도했지만 도움이되었지만 양식 크기를 조금 더 늦게 조정했습니다.

이 깜박임을 방지하기 위해 다른 방법이 있습니까?

답변

10

내 소유자가 그려진 목록 상자에도 비슷한 문제가있었습니다. 내 솔루션은 BufferedGraphics 개체를 사용하는 것이 었습니다. 주인이 그려,하지만 어쩌면 그것은 당신에게 영감을 줄 것이다. 내가있는 TextRenderer 내가 TextFormatFlags.Prese을 suppled하지 않는 한 올바른 위치로 렌더링 어려움을 남겼

rveGraphicsTranslateTransform. 대신 P/Invoke를 사용하여 BitBlt를 호출하여 그래픽 컨텍스트간에 픽셀을 직접 복사 할 수있었습니다. 나는 이것을 두 가지 악의 적은 것으로 선택했다.

/// <summary> 
/// This class is a double-buffered ListBox for owner drawing. 
/// The double-buffering is accomplished by creating a custom, 
/// off-screen buffer during painting. 
/// </summary> 
public sealed class DoubleBufferedListBox : ListBox 
{ 
    #region Method Overrides 
    /// <summary> 
    /// Override OnTemplateListDrawItem to supply an off-screen buffer to event 
    /// handlers. 
    /// </summary> 
    protected override void OnDrawItem(DrawItemEventArgs e) 
    { 
     BufferedGraphicsContext currentContext = BufferedGraphicsManager.Current; 

     Rectangle newBounds = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height); 
     using (BufferedGraphics bufferedGraphics = currentContext.Allocate(e.Graphics, newBounds)) 
     { 
      DrawItemEventArgs newArgs = new DrawItemEventArgs(
       bufferedGraphics.Graphics, e.Font, newBounds, e.Index, e.State, e.ForeColor, e.BackColor); 

      // Supply the real OnTemplateListDrawItem with the off-screen graphics context 
      base.OnDrawItem(newArgs); 

      // Wrapper around BitBlt 
      GDI.CopyGraphics(e.Graphics, e.Bounds, bufferedGraphics.Graphics, new Point(0, 0)); 
     } 
    } 
    #endregion 
} 
+0

난 그냥이 구현 그것은 완벽하게 작동합니다. – test

+1

@ 에릭 : 어디서 GDI를 구합니까? 그것은 레퍼런스인가? 예를 들어'Graphics GDI = this.CreateGraphics(); '를 추가하려했지만 CopyGraphics 메서드가 없습니다. 또는 이전에 Gdi32.dll을 가져 왔습니까? – Matt

+0

알았어 - 지금 일해. 나는'GDI32.dll'을'BitBlt' 메서드와 함께 추가하고'GDI.CopyGraphics (...) '로 감싸고 이제는 작동합니다 ... 유일하게 원래 ListBox와 똑같이 깜박입니다. 어떤 아이디어로 그것을 고치는 법? – Matt

2

당신은 체크 박스와리스트 뷰 컨트롤로 전환하는 문제를 향상되는지 확인할 수 있습니다. WinForms ListBox는 천재의 스트로크가 아니기 때문에 다루기가 쉽지 않습니다. 크기 조절 동작은 DoubleBuffered=true과 같습니다.

또는 빈 폼 브러시를 제공하거나 아무 것도하지 않고 을 반환하여 WM_ERASEBKND을 재정 의하여 부모 폼 배경 그림을 재정 의하여 깜박임을 줄일 수 있습니다. (귀하의 컨트롤이 상위 폼의 전체 클라이언트 영역을 다루는 경우에는 괜찮습니다. 그렇지 않으면 좀 더 복잡한 배경 드로잉 메서드가 필요합니다.)

저는 이것을 Win32 응용 프로그램에서 성공적으로 사용했지만, 폼 컨트롤은이 기능을 렌더링하지 않는 자체 마법을 추가합니다.

0

WM_SETREDRAW 메시지를 컨트롤로 보내는 방식으로 처리됩니다.

const int WM_SETREDRAW = 0x0b; 

Message m = Message.Create(yourlistbox.Handle, WM_SETREDRAW, (IntPtr) 0, (IntPtr) 0); 
yourform.DefWndProc(ref m); 

// do your updating or whatever else causes the flicker 

Message m = Message.Create(yourlistbox.Handle, WM_SETREDRAW, (IntPtr) 1, (IntPtr) 0); 
yourform.DefWndProc(ref m); 

은 참조 : WM_SETREDRAW reference at Microsoft고정 링크

다른 사람이 .NET에서 윈도우 메시지를 사용하는 경우, 필요에 따라 본 게시물을 업데이트하십시오.

+0

깜박임은 크기 조정에 의한 것이므로이 isn이 아니다. 최적의 솔루션입니다. 그러나 어쨌든 그것을 할 수도 있습니다. – SLaks

+0

내 ListBox에서 깜박 거리는 문제가 해결되지 않습니다. – AlainD

0

깜박임의 특정 문제를 해결하지는 않지만이 유형의 문제에 대해 자주 효과적인 방법은 ListBox 항목의 최소 상태를 캐시하는 것입니다. 그런 다음 각 항목에 대해 계산을 수행하여 ListBox를 다시 그릴 필요가 있는지 여부를 결정하십시오. 적어도 하나의 항목을 업데이트해야하는 경우에만 ListBox를 업데이트하십시오 (물론 다음주기에 캐시에 새 상태를 저장하십시오).