VB.NET 2008/VB - 컨트롤

컨트롤 - 소유자가 그린 기본 제공 컨트롤 지원

본클라쓰 2011. 4. 25. 09:53

 

사용자 지정 그리기라고도 하는 Windows Forms의 소유자 그리기는 특정 컨트롤의 시각적 모양을 변경하는 기술이다.

 

일반적으로 Windows에서는 BackColor와 같은 속성 설정으로 컨트롤의 모양을 결정하여 그리기 작업을 자동으로 처리한다. 소유자 그리기를 사용하면 속성을 통해 사용할 수 없는 모양의 요소를 변경하는 등의 그리기 프로세스를 제어할 수 있다. 예를 들어, 컨트롤에서 표시되는 텍스트의 색을 설정할 수 있지만 한 가지 색만 사용하도록 제한되는 경우가 많다. 소유자 그리기를 사용하면 텍스트의 일부는 검정으로 표시하고 일부는 빨강으로 표시할 수 있다.

 

실제로 사용자 그리기는 폼에 그래픽을 그리는 것과 비슷하다. 예를 들어, 폼의 Paint 이벤트에 대한 처리기에서 그래픽 메서드를 사용하여 ListBox 컨트롤을 에뮬레이트할 수 있지만 이 경우 모든 사용자 상호 작용을 처리하는 고유한 코드를 작성해야 한다. 소유자 그리기를 사용하는 경우 컨트롤은 사용자가 작성한 코드를 사용하여 컨트롤의 내용을 그리며, 코드가 없는 경우에는 컨트롤의 내장 기능을 모두 유지한다. 그래픽 메서드를 사용하여 각 항목을 컨트롤에 그리거나 각 항목의 일부 측면만을 사용자 지정하고 다른 측면에 대해서는 기본 모양을 사용할 수 있다.

 

 

소유자 그리기를 지원한는 컨트롤에서 소유자 그리기를 수행하는 경우에는 일반적으로 한 개의 속성을 설정하고 하나 이상의 이벤트를 처리하게 된다.

 

소유자 그리기를 지원하는 대부분의 컨트롤에는 컨트롤 자체가 그려질 때 해당 그리기 관련 이벤트를 발생시킬지 여부를 나타내는 OwnerDraw 또는 DrawMode 속성이 있다.

 

OwnerDraw 또는 DrawMode 속성이 없는 컨트롤에는 자동으로 발생하는 그리기 이벤트를 제공하는 DataGridView 컨트롤과 고유한 그리기 관련 이벤트를 가진 외부 렌더링 클래스를 사용하여 그려지는 ToolStrip 컨트롤이 있다.

 

매우 다양한 종류의 그리기 이벤트가 있지만 한 컨트롤에서 단일 항목을 그리는 경우에는 일반적인 그리기 이벤트가 발생한다. 이 이벤트 처리기는 그려지는 항목과 그리기에 사용할 수 있는 도구에 대한 정보가 들어 있는 EventArgs 개체를 받는다. 예를 들어, 이 개체에는 일반적으로 부모 컬렉셕 내에서 항목의 인덱스 번호, 항목의 표시 경계를 나타내는 Rectangle 및 그리기 메서드를 호출하기 위한 Graphics 개체가 들어 있다. EventArgs 개체는 일부 이벤트에 대해 배경이나 포커스 사각형과 같은 항목의 일부 측면을 그리기 위해 호출할 수 있는 항목과 메서드에 대한 추가 정보를 기본적으로 제공한다.

 

소유자 그리기 사용자 지정이 포함된 다시 사용할 수 있는 컨트롤을 만들려면 소유자 그리기를 지원하는 컨트롤 클래스에서 파생되는 새 클래스를 만든다. 그리기 이벤트를 처리하는 것보다 새 클래스의 해당 onEventName 메서드에 대한 재정의에 소유자 그리기 코드를 포함하는 것이 좋다. 이 경우 컨트롤의 사용자가 소유자가 그리기 이벤트를 처리하고 추가 사용자 지정을 제공할 수 있도록 기본 클래스 onEventName 메서드를 호출해야 한다.

 

 

ListBox 및 ComboBox 컨트롤을 사용하면 개별 항목을 모두 동일한 크기 또는 각기 다른 크기로 컨트롤에 그릴 수 있다.

 

각 항목을 같은 크기로 그리려면 DrawMode 속성을 OwnerDrawFixed로 설정하고 DrawItem 이벤트를 처리한다.

 

각 항목을 서로 다른 크기로 그리려면 DrawMode 속성을 OwnerDrawVariable로 설정하고 MeasureItem 및 DrawItem 이벤트를 모두 처리합니다. MeasureItem 이벤트를 사용하면 해당 항목에 대해 DrawItem 이벤트가 발생하기 전에 항목의 크기를 나타낼 수 있다.

 

 

MeasureItem 이벤트는 소유자가 그린 ListBox가 만들어지고 목록 항목의 크기가 결정될 때 발생한다.

 

' Handle the DrawItem event for an owner-drawn ListBox.
Private Sub ListBox1_DrawItem(ByVal sender As ObjectByVal e As DrawItemEventArgs) Handles _ ListBox1.DrawItem

    ' If the item is the selected item, then draw the rectangle filled in
    ' blue. The item is selected when a bitwise And of the State property
    ' and the DrawItemState.Selected property is true.
    If (e.State And DrawItemState.Selected = DrawItemState.Selected) Then
        e.Graphics.FillRectangle(Brushes.CornflowerBlue, e.Bounds)
    Else
        ' Otherwise, draw the rectangle filled in beige.
        e.Graphics.FillRectangle(Brushes.Beige, e.Bounds)
    End If

    ' Draw a rectangle in blue around each item.
    e.Graphics.DrawRectangle(Pens.Blue, e.Bounds)

    ' Draw the text in the item.
    e.Graphics.DrawString(Me.ListBox1.Items(e.Index), Me.Font, Brushes.Black, e.Bounds.X, e.Bounds.Y)

    ' Draw the focus rectangle around the selected item.
    e.DrawFocusRectangle()
End Sub

 

 

DrawItem 이벤트는 소유자가 그린 ListBox의 시각적 측면이 변경될 때 발생한다.

 

' Handle the MeasureItem event for an owner-drawn ListBox.
Private Sub ListBox1_MeasureItem(ByVal sender As ObjectByVal e As MeasureItemEventArgs) Handles _ ListBox1.MeasureItem

    ' Cast the sender object back to ListBox type.
    Dim theListBox As ListBox = CType(sender, ListBox)

    ' Get the string contained in each item.
    Dim itemString As String = CType(theListBox.Items(e.Index), String)

    ' Split the string at the " . "  character.
    Dim resultStrings() As String = itemString.Split(".")

    ' If the string contains more than one period, increase the
    ' height by ten pixels; otherwise, increase the height by
    ' five pixels.
    If (resultStrings.Length > 2) Then
        e.ItemHeight += 10
    Else
        e.ItemHeight += 5
    End If

End Sub