실버라이트 팁

DrawingVisual 객체를 이용해서 컨트롤 그리기 Linus 평점: 없음 조회: 6456

WPF나 실버라이트에서 한 화면에 수많은 컨트롤을 표시하면 퍼포먼스가 많이 떨어지는 현상을 많이 겪으실 겁니다.

그럴 경우 DrawingVisual이라는 객체를 사용해서 직접 컨트롤을 그리는 기능을 제공합니다.

※현재는 WPF에서만 사용이 가능하며 추후 실버라이트 5 버전에서 사용 가능하도록 업데이트 될 예정입니다.

아래 예제를 통해서 간단하게 사용하는 방법을 알아보겠습니다.

1. FrameworkElement 상속받기

클래스 하나를 생성하고 FrameworkElement를 상속받습니다.
그리고 OnRender 매서드를 Override 합니다.

public class DrawingControl : FrameworkElement

    {

        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)

        {

        }

    }


OnRender 매서드는 DrawingContext라는 전달인자를  가지고 있는데 이 객체를 통해서 우리는 화면에 원하는 컨트롤을 그릴 수 있습니다.
DrawingContext가 그리기를 지원하는 컨트롤은 아래와 같습니다.

  • Rectangle
  • Ellipse
  • Geometry
  • GlyphRun
  • Image
  • Line
  • RoundedRectangle
  • Text
  • Video

2. 사각형 그리기

다음은 OnRender매서드를 오버라이드하고 drawingContext를 이용해서 사각형을 그리는 예제입니다.

namespace WpfApplication1

{

    public class DrawingControl : FrameworkElement

    {

        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)

        {

            drawingContext.DrawRectangle(Brushes.Blue, new Pen(Brushes.Red, 2), new Rect(0, 0, 120, 22));

        }

    }

}

결과>


또한 DrawingContext를 이용해서 TextBlock을 사용하지 않고 화면에 직접 글씨를 쓸 수도 있습니다.

3. DrawingContext를 이용해서 글씨쓰기

namespace WpfApplication1

{

    public class DrawingControl : FrameworkElement

    {

        protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)

        {

            drawingContext.DrawRectangle(Brushes.Black, new Pen(Brushes.Red, 2), new Rect(0, 0, 120, 22));

            Typeface typeface = new Typeface("Times New Roman");

 

            FormattedText ft = new FormattedText("Hello Ryunad !!!!",

System.Globalization.CultureInfo.CurrentCulture,     

System.Windows.FlowDirection.LeftToRight,

                                                                  typeface,

                                                                  14,

                                                                  Brushes.Yellow);

 

            drawingContext.DrawText(ft, new Point(6, 3));

        }

    }

}

글씨를 쓰기 위해서는 FormattedText라는 객체를 생성해서 글씨의 사이즈나 글씨체, 색상 등을 설정해주셔야 합니다.
다음은 결과화면입니다.

결과>

3. DrawingVisual 객체를 이용해서 동적으로 컨트롤 그리기

자신이 원하고자 하는 시점에 컨트롤을 그리고자 하는 경우에 다음과 같이 하시면 됩니다.

먼저 VisualCollection 객체를 하나 전역변수로 선언합니다.

VisualCollection은 현재 화면에 그리고 있는 Visual객체를 담는 Collection입니다.
이곳에 추가된 Visual객체는 화면에 그려지게 되고 이곳에서 제거되면 화면에서도 제거됩니다.
또한 이 VisualCollection의 아이템을 수정하게 되면 해당 아이템을 다시그립니다.

다음으로 VisualChildrenCount 프로퍼티와 GetVisualChild라는 매서드를 오버라이드 합니다.
이 프로퍼티와 매서드는 반드시 오버라이드 해주셔야 정상적으로 동작을 합니다.

다음은 예제 코드입니다.

namespace WpfApplication1

{

    public class DrawingControl : FrameworkElement

    {

        VisualCollection _visualChildren;

 

        protected override int VisualChildrenCount

        {

            get

            {

                return _visualChildren.Count ;

            }

        }

 

        protected override Visual GetVisualChild(int index)

        {

            return _visualChildren[index];

        }

 

        public DrawingControl()

        {

            _visualChildren = new VisualCollection(this);

        }

 

        public DrawingVisual GetNewVisual()

        {

            DrawingVisual newVisual = new DrawingVisual();

            _visualChildren.Add(newVisual);

 

            return newVisual;

        }

 

        public void Draw()

        {

            var newVisual = GetNewVisual();

 

            DrawingContext drawingContext = newVisual.RenderOpen();

 

            drawingContext.DrawRectangle(Brushes.Black, new Pen(Brushes.Red, 2), new Rect(0, _visualChildren.Count * 22, 120, 22));

 

            Typeface typeface = new Typeface("Times New Roman");

           

            drawingContext.Close();

        }

 

        public void RemoveVisual()

        {

            if (_visualChildren.Count == 0)

                return;

 

            var removedVisual = _visualChildren[0];

            _visualChildren.Remove(removedVisual);

        }

    }

}

새 DrawingVisual 객체를 생성하고 VisualCollection에 등록합니다.
그 다음 DrawingVisual의 RenderOpen() 매서드를 통하여 DrawingContext 객체를 반환받은 후에 사용하시면 됩니다.



4. ItemsControl과 DrawingVisual 간의 CPU 점유율 비교

다음은 아이템 5000개를 한 화면에 표시했을 때 CPU점유율을 나타내는 것입니다.
위쪽은 ItemsControl을 이용한 화면이고 아래쪽은 DrawingVisual객체를 이용해서 컨트롤을 그렸을 때입니다.

                                       [ItemsControl]          

                                        [DrawingControl]


절반에 가까운 CPU점유율의 차이를 보여주고 있습니다만 실제 체감 속도는 그다지 차이가 없는 것을 확인 할 수 있습니다.

마무리...

오랜만에 글쓰려고 하니까 잘 안써지네요. 
혹시라도 위 글과 관련해서 이해가 잘 안가는 부분이 있으시면 답변달아드리겠습니다.

모두 즐코하세요~~

 

원문 : ryunad.tistory.com


태그 : , DrawingContext DrawingVisual
작성자 정보
Linus
Level 61
 [EXP.44/250]

메일:  비공개

글등록 +12 1932 덧글등록 +3 1263
자기소개
글 공유하기 |
  tweet facebook
2011-12-08 오후 5:55:32
나도한마디
태그로 엮인글
[ASP.NET Q&A] ASP.net Radiobutton 선택 변환값을 AUTOPOSTBACK="fales" 상태에서 변경방법[1]  은빛늑대
[C#.NET Q&A] 다른 PC의 로컬 DB에 접속할수 있을까요?[2]  은빛늑대
[C#.NET Q&A] dev gridview 스크롤 이동 관련해서 질문 드립니다.[1]  두더쥐
[구인&교육정보] 프로그램 개발자 분을 모십니다.  검은천사
[구인&교육정보] C++ / C# 프로그램 가능하신분 모집 합니다.  검은천사
[C#.NET Q&A] c# mssql csv파일 업로드중 질문입니다 ㅠ_ㅠ  용서니
[C#.NET Q&A] 엑셀 오토메이션 질문좀 드리겠습니다.[1]  조성진
[ASP.NET Q&A] OnClientClick 에서 버튼 비활성화 후에 onclick 실행[2]  Belbo
[C#.NET Q&A] input 박스안에 입력된 값의 유효성 체크 방법 문의 합니다. (저장 버튼 클릭 시)[2]  신입
[C#.NET Q&A] c# 질문이 있습니다.....[2]+1  닷지
글리스트
실버라이트에서 이미지 보정 예제 (Pixel Manipulation in Silverlight)  sky
실버라이트 5 살펴보기 강좌 (10 Laps around Silverlight 5)[2]  sky
HTML 5 & Silverlight 5  sky
xap를 서버에 변경했는데 client에서는 변경이 안 되는 경우  시선
blend 단축키[1]  sa2랑
실버라이트에서 지원하는 미디어 형식이에요  sa2랑
Silverlight- Prism 라이브러리/툴킷/참고 예제 사이트입니다.  sky
[UX스터디 첫째주 자료] MS UX 프로그래밍의 소개 파일첨부 sky
vs2010에서 silverlight5프로젝트를 할때 open in expression blend 수정  시선
Behavior 로 구현한 Silverlight TextBox Watermark[1]+1  joseph
 ★현재글->   DrawingVisual 객체를 이용해서 컨트롤 그리기  Linus
[실버라이트 스터디 3주차] 데이터그리드의 Row Detail과 Javascript Access #2 파일첨부 시선
[실버라이트 스터디 3주차] 데이터그리드의 Row Detail과 Javascript Access #1 파일첨부 시선
[실버라이트 스터디 2주차] 데이터그리드에서 이미지 추가/수정/삭제[1]  시선
SECTION02. 익스프레션 블렌드의 레이아웃  짱묜
[실버라이트 스터디] 6월 25일 더디어 실버라이트 스터디를 시작했습니다[5]  시선
실버라이트4에서 XAML 디버깅하기[4]+1  Linus
STEP03. 익스프레션 블렌드의 툴 박스 III  짱묜
STEP03. 익스프레션 블렌드의 툴 박스 II[1]  짱묜
STEP03. 익스프레션 블렌드의 툴 박스 I[2]  짱묜
Silverlight의 Navigation Framework 사용하기 - (1)[1]  Linus