반응형

C# 폼 디자이너에서 폼은 더블 버퍼링 속성을 적용할 수 있지만 대부분의 컨트롤은 더블 버퍼링 속성이 보이지 않는다.

컨트롤에 더블 버퍼링을 적용해 보자.

 

폼 속성에 있는 더블 버퍼링

 

폼에 PictureBox, Panel, Timer, Button을 적당히 배치한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        Bitmap myBitmap;
 
        public Form1()
        {
            InitializeComponent();
 
            timer1.Enabled = true;
            timer1.Interval = 100;
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    myBitmap = new Bitmap(dlg.FileName);
                }
                dlg.Dispose();
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }
 
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (myBitmap != null)
            {
                e.Graphics.DrawImage(myBitmap, 00);
            }
        }
 
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (myBitmap != null)
            {
                e.Graphics.DrawImage(myBitmap, 00);
            }
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Invalidate();
            panel1.Invalidate();
        }
    }
}
 

 

소스를 입력하고 빌드한다.

 

실행하면 PictureBox는 깜빡이지 않지만 Panel에 그려진 이미지는 심하게 깜빡인다.

PictureBox는 기본적으로 더블 버퍼링이 적용되어 있다.

 

1
2
3
System.Reflection.PropertyInfo controlProperty = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
Text = controlProperty.GetValue(pictureBox1).ToString();
 

 

위 명령어를 실행하면 타이틀 바에 True가 표시된다.

 

Panel 클래스를 상속하고 더블 버퍼링 속성을 적용한 클래스를 정의해 보자.

 

 

Panel 클래스를 상속하는 DoubleBufferedPanel 클래스를 정의한다.

DoubleBuffered 프로퍼티는 protected로 지정되어 있기 때문에 자식 클래스에서 접근이 가능하다.

protected virtual bool DoubleBuffered { get; set; }

 

디자이너 소스에서 DoubleBufferedPanel 클래스로 Panel 오브젝트를 생성하도록 수정한다.

다시 컴파일 하고 실행하면 Panel에 표시된 이미지도 더 이상 깜빡이지 않는다.

 

하지만 컴파일 에러는 없지만 폼 디자이너에서 위와 같은 에러가 발생한다.

The service System.Windows.Forms.Design.ISelectionUIService already exists in the service container. Parameter name: serviceType

 

이번엔 컨트롤에 더블 버퍼링을 적용할 수 있는 함수를 만들어 보자.

 

1
2
3
4
5
6
7
// This helper method will not turn on double buffering if the person is running in remote desktop.
public static void SetDoubleBuffering(System.Windows.Forms.Control control, bool value)
{
    System.Reflection.PropertyInfo controlProperty = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
    controlProperty.SetValue(control, value, null);
}
 

 

DoubleBufferedPanel 클래스 관련 내용을 삭제하고 SetDoubleBuffering()을 정의한다.

생성자나 다른 필요한 곳에서 SetDoubleBuffering(panel1, true)와 같이 설정하면 컨트롤에 더블 버퍼링이 적용되고 폼 디자이너도 에러가 발생하지 않는다.

 

반응형
Posted by J-sean
: