it-swarm-ko.tech

폼에서 .NET 컨트롤을 두 번 버퍼링하는 방법은 무엇입니까?

깜박임이 발생하는 양식에 컨트롤의 protected DoubleBuffered 속성을 설정하려면 어떻게해야합니까?

47
Ian Boyd

다음은 더미 솔루션 의보다 일반적인 버전입니다.

리플렉션을 사용하여 protected DoubleBuffered 속성을 얻은 다음 true 로 설정할 수 있습니다.

참고 : 개발자 세금 납부 가 아니라 사용자가 터미널 서비스 세션 (예 : 원격 데스크톱)이 도우미 메서드는 사용자가 원격 데스크톱에서 실행중인 경우 이중 버퍼링을 설정하지 않습니다.

public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
   //Taxes: Remote Desktop Connection and painting
   //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
   if (System.Windows.Forms.SystemInformation.TerminalServerSession)
      return;

   System.Reflection.PropertyInfo aProp = 
         typeof(System.Windows.Forms.Control).GetProperty(
               "DoubleBuffered", 
               System.Reflection.BindingFlags.NonPublic | 
               System.Reflection.BindingFlags.Instance);

   aProp.SetValue(c, true, null); 
}
85
Ian Boyd

확인 이 스레드

해당 답변의 핵심을 반복하면 창에서 WS_EX_COMPOSITED 스타일 플래그를 설정하여 폼과 모든 컨트롤을 이중 버퍼링 할 수 있습니다. 스타일 플래그는 XP부터 사용할 수 있습니다. 페인팅 속도는 빨라지지 않지만 전체 창은 오프 스크린 버퍼로 그려지고 한 번의 충돌로 화면에 깜빡입니다. 눈에 띄는 페인팅 아티팩트없이 사용자의 눈에 즉시 보입니다. 완전히 문제가되는 것은 아니며, 일부 비주얼 스타일 렌더러는 특히 탭이 너무 많을 때 TabControl에 결함이 생길 수 있습니다. YMMV.

이 코드를 양식 클래스에 붙여 넣으십시오.

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

이 기술과 Winform의 이중 버퍼 지원 간의 큰 차이점은 Winform의 버전은 한 번에 하나의 컨트롤에서만 작동한다는 것입니다. 여전히 각 개별 컨트롤 페인트 자체를 볼 수 있습니다. 특히 페인트되지 않은 컨트롤 사각형이 창의 배경과 크게 대조되는 경우 깜박임 효과처럼 보일 수 있습니다.

65
Hans Passant
System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);

Ian 터미널 서버에서 이것을 사용하는 것에 대한 더 많은 정보가 있습니다.

18
dummy
public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}
12
Arno

한 가지 방법은 더블 버퍼링하려는 특정 컨트롤을 확장하고 컨트롤의 ctor 내에서 DoubleBuffered 속성을 설정하는 것입니다.

예를 들어 :

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}
8
Jeff Hubbard

확장 방법 컨트롤의 이중 버퍼링을 켜거나 끄려면

public static class ControlExtentions
{
    /// <summary>
    /// Turn on or off control double buffering (Dirty hack!)
    /// </summary>
    /// <param name="control">Control to operate</param>
    /// <param name="setting">true to turn on double buffering</param>
    public static void MakeDoubleBuffered(this Control control, bool setting)
    {
        Type controlType = control.GetType();
        PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(control, setting, null);
    }
}

사용법 (예 : DataGridView DoubleBuffered 만드는 방법) :

DataGridView _grid = new DataGridView();
//  ...
_grid.MakeDoubleBuffered(true);
5
MajesticRa

nobugz 그의 링크에서 메소드의 크레딧을 얻습니다. 이 재정의를 양식에 추가하십시오.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

이것은 Windows 7에서 컨트롤 무거운 양식의 크기를 조정할 때 큰 검은 블록이 나타납니다. 대신 컨트롤이 바운스됩니다! 그러나 더 좋습니다.

5
Chris S

이중 버퍼링을 시도하기 전에 SuspendLayout ()/ResumeLayout ()이 문제를 해결하는지 확인하십시오.

4
Joel Coehoorn

이로 인해 추적 할 때까지 타사 컨트롤을 사용하여 2 일 동안 lot 슬픔을 일으켰습니다.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

최근에 다른 여러 컨트롤이 포함 된 컨트롤의 크기를 조정하거나 다시 그릴 때 많은 구멍 (삭제)이 발생했습니다.

WS_EX_COMPOSITED 및 WM_SETREDRAW를 시도했지만 이것을 사용할 때까지 아무것도 작동하지 않았습니다.

private void myPanel_SizeChanged(object sender, EventArgs e)
{
     Application.DoEvents();
}

그냥 전달하고 싶었습니다.

4
dnennis

이 훌륭한 솔루션의 vb.net 버전 .... :

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or &H2000000
        Return cp
    End Get
End Property
2
Flip70

컨트롤을 자신의 클래스로 상속하고 속성을 설정할 수도 있습니다. 이 방법은 모든 컨트롤에서 동일한 설정을 많이하는 경향이있는 경우에도 좋습니다.

1
MagicKat

폼에서 DoubleBuffered 설정을 설정하면 여기에 나열된 모든 속성이 자동으로 설정됩니다.

0
ljs