다음을 통해 공유


.NET Framework PropertyGrid 컨트롤을 최대한 활용

 

Mark Rideout
Microsoft Corporation

적용 대상:
   Microsoft® .NET® Framework
   Microsoft® Visual Studio® .NET

요약: Microsoft .NET Framework PropertyGrid 컨트롤과 애플리케이션에 맞게 사용자 지정하는 방법을 이해하는 데 도움이 됩니다. (인쇄된 페이지 37개)

콘텐츠

PropertyGrid 컨트롤 소개
PropertyGrid 컨트롤 만들기
PropertyGrid 컨트롤을 사용할 위치
개체 선택
PropertyGrid 컨트롤 사용자 지정
복합 속성 표시
속성에 대한 사용자 지정 UI 제공
결론

PropertyGrid 컨트롤 소개

Microsoft® Visual Basic® 또는 Microsoft Visual Studio .NET을 사용한 경우 속성 브라우저를 사용하여 하나 이상의 개체의 속성을 찾아보고, 보고, 편집했습니다. .NET Framework PropertyGrid 컨트롤은 Visual Studio .NET에 있는 속성 브라우저의 핵심입니다. PropertyGrid 컨트롤은 모든 개체 또는 형식에 대한 속성을 표시하고 주로 리플렉션을 사용하여 항목의 속성을 검색합니다. (리플렉션은 런타임에 형식 정보를 제공하는 기술입니다.)

다음 스크린샷은 양식에 배치할 때 PropertyGrid 가 어떻게 보이는지 보여줍니다.

그림 1. 양식의 PropertyGrid

PropertyGrid에는 다음 부분이 포함됩니다.

  • 속성
  • 확장 가능한 속성
  • 속성 범주 제목
  • 속성 설명
  • 속성 편집기
  • 속성 탭
  • 명령 창(컨트롤의 디자이너가 노출하는 디자이너 동사를 표시)

PropertyGrid 컨트롤 만들기

Visual Studio .NET을 사용하여 PropertyGrid 컨트롤을 만들려면 기본적으로 포함되지 않으므로 PropertyGrid 컨트롤을 도구 상자에 추가해야 합니다. 도구 메뉴에서 도구 상자 사용자 지정을 선택합니다. 대화 상자에서 프레임워크 구성 요소 탭을 선택한 다음 , PropertyGrid를 선택합니다.

명령줄에서 코드를 컴파일하는 경우 /reference 옵션을 사용하고 System.Windows.Forms.dll 지정합니다.

다음 코드에서는 PropertyGrid 컨트롤을 만들고 양식에 추가하는 방법을 보여 줍니다.

' Visual Basic

Imports System
Imports System.Drawing
Imports System.ComponentModel
Imports System.Windows.Forms
Imports System.Globalization

Public Class OptionsDialog
   Inherits System.Windows.Forms.Form

   Private OptionsPropertyGrid As System.Windows.Forms.PropertyGrid

   Public Sub New()
      MyBase.New()

      OptionsPropertyGrid = New PropertyGrid()
      OptionsPropertyGrid.Size = New Size(300, 250)

      Me.Controls.Add(OptionsPropertyGrid)
      Me.Text = "Options Dialog"
   End Sub
End Class


//C#

using System;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
using System.Globalization;

public class OptionsDialog : System.Windows.Forms.Form
{
   private System.Windows.Forms.PropertyGrid OptionsPropertyGrid;
   public OptionsDialog()
   {
      OptionsPropertyGrid = new PropertyGrid();
      OptionsPropertyGrid.Size = new Size(300, 250);

      this.Controls.Add(OptionsPropertyGrid);
      this.Text = "Options Dialog";
   }

   [STAThread]
   static void Main() 
   {
      Application.Run(new OptionsDialog());
   }
}

PropertyGrid 컨트롤을 사용할 위치

애플리케이션에는 사용자가 PropertyGrid와 상호 작용하도록 하여 보다 풍부한 편집 환경을 제공할 수 있는 다양한 위치가 있습니다. 한 가지 예는 사용자가 설정할 수 있는 몇 가지 "설정" 또는 옵션이 있는 애플리케이션입니다. 라디오 단추, 콤보 상자 또는 텍스트 상자를 사용하여 이러한 옵션을 나타낼 수 있습니다. 대신, 이 문서에서는 PropertyGrid 컨트롤을 사용하여 애플리케이션 옵션을 설정하기 위한 옵션 창을 만드는 프로세스를 단계별로 진행합니다. 위에서 만든 양식은 OptionsDialog 옵션 창의 시작입니다. 이제 애플리케이션 설정에 매핑되는 모든 속성을 포함하는 라는 AppSettings 클래스를 만듭니다. 개별 변수를 사용하는 대신 별도의 클래스를 만드는 경우 설정을 훨씬 쉽게 관리하고 유지 관리할 수 있습니다.

' Visual Basic

Public Class AppSettings
    Private _saveOnClose As Boolean = True
    Private _greetingText As String = "Welcome to your application!"
    Private _maxRepeatRate As Integer = 10
    Private _itemsInMRU As Integer = 4

    Private _settingsChanged As Boolean = False
    Private _appVersion As String = "1.0"

    Public Property SaveOnClose() As Boolean
        Get
            Return _saveOnClose
        End Get
        Set(ByVal Value As Boolean)
            SaveOnClose = Value
        End Set
    End Property

    Public Property GreetingText() As String
        Get
            Return _greetingText
        End Get
        Set(ByVal Value As String)
            _greetingText = Value
        End Set
    End Property

    Public Property ItemsInMRUList() As Integer
        Get
            Return _itemsInMRU
        End Get
        Set(ByVal Value As Integer)
            _itemsInMRU = Value
        End Set
    End Property

    Public Property MaxRepeatRate() As Integer
        Get
            Return _maxRepeatRate
        End Get
        Set(ByVal Value As Integer)
            _maxRepeatRate = Value
        End Set
    End Property

    Public Property SettingsChanged() As Boolean
        Get
            Return _settingsChanged
        End Get
        Set(ByVal Value As Boolean)
            _settingsChanged = Value
        End Set
    End Property

    Public Property AppVersion() As String
        Get
            Return _appVersion
        End Get
        Set(ByVal Value As String)
            _appVersion = Value
        End Set
    End Property
End Class


//C#

public class AppSettings{
    private bool saveOnClose = true;
    private string greetingText = "Welcome to your application!";
    private int itemsInMRU = 4;
    private int maxRepeatRate = 10;
    private bool settingsChanged = false;
    private string appVersion = "1.0";
    
    public bool SaveOnClose
    {
        get { return saveOnClose; }
        set { saveOnClose = value;}
    }
    public string GreetingText
    {
        get { return greetingText; }
        set { greetingText = value; }
    }
    public int MaxRepeatRate
    {
        get { return maxRepeatRate; }
        set { maxRepeatRate = value; }
    }
    public int ItemsInMRUList
    {
        get { return itemsInMRU; }
        set { itemsInMRU = value; }
    }
    public bool SettingsChanged
    {
        get { return settingsChanged; }
        set { settingsChanged = value; }
    }
    public string AppVersion
    {
        get { return appVersion; }
        set { appVersion = value; }
    }
}

옵션 창의 PropertyGrid 는 이 클래스를 조작하므로 새 파일이나 양식의 소스 코드 아래쪽에 있는 애플리케이션 프로젝트에 클래스 정의를 추가합니다.

개체 선택

PropertyGrid가 표시하는 항목을 식별하려면 PropertyGrid.SelectedObject 속성을 개체 instance 설정합니다. PropertyGrid는 나머지를 수행합니다. SelectedObject를 설정할 때마다 PropertyGrid는 표시된 속성을 새로 고칩니다. 이렇게 하면 속성을 강제로 새로 고치거나 런타임에 개체 간에 전환할 수 있는 쉬운 방법이 제공됩니다. PropertyGrid.Refresh 메서드를 호출하여 속성을 새로 고칠 수도 있습니다.

계속하려면 생성자의 코드를 OptionsDialog 업데이트하여 개체를 AppSettings 만들고 PropertyGrid.SelectedObject 속성으로 설정합니다.

' Visual Basic

   Public Sub New()
      MyBase.New()

      OptionsPropertyGrid = New PropertyGrid()
      OptionsPropertyGrid.Size = New Size(300, 250)

      Me.Controls.Add(OptionsPropertyGrid)
      Me.Text = "Options Dialog"

      ' Create the AppSettings class and display it in the PropertyGrid.      Dim appset as AppSettings = New AppSettings()      OptionsPropertyGrid.SelectedObject = appset
   End Sub


//C#

   public OptionsDialog()
   {
      OptionsPropertyGrid = new PropertyGrid();
      OptionsPropertyGrid.Size = new Size(300, 250);

      this.Controls.Add(OptionsPropertyGrid);
      this.Text = "Options Dialog";

      // Create the AppSettings class and display it in the PropertyGrid.      AppSettings appset = new AppSettings();      OptionsPropertyGrid.SelectedObject = appset;
   }

애플리케이션을 컴파일하고 실행합니다. 다음 스크린샷은 어떻게 보이는지 보여줍니다.

그림 2. PropertyGrid에서 선택한 AppSettings 클래스

PropertyGrid 컨트롤 사용자 지정

필요에 맞게 PropertyGrid의 일부 시각적 측면을 수정할 수 있습니다. 일부 속성이 표시되는 방식을 변경하고 일부 속성을 표시하지 않도록 선택할 수도 있습니다. PropertyGrid는 얼마나 사용자 지정할 수 있나요?

PropertyGrid의 시각적 측면 변경

PropertyGrid의 많은 시각적 측면은 사용자 지정할 수 있습니다. 다음은 목록의 일부입니다.

  • HelpBackColor, HelpForeColorHelpVisible 속성을 통해 배경색을 변경하거나 글꼴 색을 변경하거나 설명 창을 숨깁니다.
  • ToolbarVisible 속성을 통해 도구 모음을 숨기고, BackColor 속성을 통해 색을 변경하고, LargeButtons 속성을 통해 큰 도구 모음 단추를 표시합니다.
  • 속성을 사전순으로 정렬하고 PropertySort 속성을 사용하여 분류합니다.
  • BackColor 속성을 통해 분할자 색을 변경합니다.
  • LineColor 속성을 통해 눈금선과 테두리를 변경합니다.

이 예제의 옵션 창에서는 도구 모음이 필요하지 않으므로 ToolbarVisiblefalse로 설정합니다. 다른 기본 설정은 유지합니다.

속성 표시 방법 변경

일부 속성이 표시되는 방식을 변경하려면 속성에 다른 특성을 적용할 수 있습니다. 특성은 리플렉션을 사용하여 런타임에 검색할 수 있는 형식, 필드, 메서드 및 속성과 같은 프로그래밍 요소에 주석을 추가하는 데 사용되는 선언적 태그입니다. 다음은 목록의 일부입니다.

  • DescriptionAttribute. 속성 아래의 설명 도움말 창에 표시되는 속성의 텍스트를 설정합니다. 활성 속성(포커스가 있는 속성)에 대한 도움말 텍스트를 제공하는 유용한 방법입니다. 속성에 MaxRepeatRate 이 특성을 적용합니다.
  • CategoryAttribute. 속성이 표에 있는 범주를 설정합니다. 범주 이름을 기준으로 속성을 그룹화하려는 경우에 유용합니다. 속성에 범주가 지정되지 않은 경우 Misc 범주에 할당됩니다. 이 특성을 모든 속성에 적용합니다.
  • BrowsableAttribute – 속성이 표에 표시되는지 여부를 나타냅니다. 이 기능은 그리드에서 속성을 숨기려는 경우에 유용합니다. 기본적으로 공용 속성은 항상 표에 표시됩니다. 속성에 SettingsChanged 이 특성을 적용합니다.
  • ReadOnlyAttribute – 속성이 읽기 전용인지 여부를 나타냅니다. 이 기능은 속성이 그리드에서 편집할 수 있기를 원하지 않는 경우에 유용합니다. 기본적으로 get 및 set 접근자 함수가 있는 public 속성은 그리드에서 편집할 수 있습니다. 속성에 AppVersion 이 특성을 적용합니다.
  • DefaultValueAttribute – 속성의 기본값을 식별합니다. 이 기능은 속성에 대한 기본값을 제공하고 나중에 속성의 값이 기본값과 다른지 확인하려는 경우에 유용합니다. 이 특성을 모든 속성에 적용합니다.
  • DefaultPropertyAttribute – 클래스의 기본 속성을 식별합니다. 클래스의 기본 속성은 그리드에서 클래스를 선택할 때 먼저 포커스를 가져옵니다. 클래스에 이 특성을 적용합니다 AppSettings .

이제 이러한 특성 중 일부를 클래스에 AppSettings 적용하여 속성이 PropertyGrid에 표시되는 방식을 변경합니다.

' Visual Basic

<DefaultPropertyAttribute("SaveOnClose")> _
Public Class AppSettings
    Private _saveOnClose As Boolean = True
    Private _greetingText As String = "Welcome to your application!"
    Private _maxRepeatRate As Integer = 10
    Private _itemsInMRU As Integer = 4

    Private _settingsChanged As Boolean = False
    Private _appVersion As String = "1.0"

    <CategoryAttribute("Document Settings"), _     DefaultValueAttribute(True)> _
    Public Property SaveOnClose() As Boolean
        Get
            Return _saveOnClose
        End Get
        Set(ByVal Value As Boolean)
            SaveOnClose = Value
        End Set
    End Property

    <CategoryAttribute("Global Settings"), _    ReadOnlyAttribute(True), _    DefaultValueAttribute("Welcome to your application!")> _
    Public Property GreetingText() As String
        Get
            Return _greetingText
        End Get
        Set(ByVal Value As String)
            _greetingText = Value
        End Set
    End Property

    <CategoryAttribute("Global Settings"), _    DefaultValueAttribute(4)> _
    Public Property ItemsInMRUList() As Integer
        Get
            Return _itemsInMRU
        End Get
        Set(ByVal Value As Integer)
            _itemsInMRU = Value
        End Set
    End Property

    <DescriptionAttribute("The rate in milliseconds that the text will repeat."), _    CategoryAttribute("Global Settings"), _    DefaultValueAttribute(10)> _
    Public Property MaxRepeatRate() As Integer
        Get
            Return _maxRepeatRate
        End Get
        Set(ByVal Value As Integer)
            _maxRepeatRate = Value
        End Set
    End Property

    <BrowsableAttribute(False),     DefaultValueAttribute(False)> _
    Public Property SettingsChanged() As Boolean
        Get
            Return _settingsChanged
        End Get
        Set(ByVal Value As Boolean)
            _settingsChanged = Value
        End Set
    End Property

    <CategoryAttribute("Version"), _    DefaultValueAttribute("1.0"), _    ReadOnlyAttribute(True)> _
    Public Property AppVersion() As String
        Get
            Return _appVersion
        End Get
        Set(ByVal Value As String)
            _appVersion = Value
        End Set
    End Property
End Class


//C#[DefaultPropertyAttribute("SaveOnClose")]
public class AppSettings{
    private bool saveOnClose = true;
    private string greetingText = "Welcome to your application!";
    private int maxRepeatRate = 10;
    private int itemsInMRU = 4;

    private bool settingsChanged = false;
    private string appVersion = "1.0";

    [CategoryAttribute("Document Settings"),    DefaultValueAttribute(true)]
    public bool SaveOnClose
    {
        get { return saveOnClose; }
        set { saveOnClose = value;}
    }

    [CategoryAttribute("Global Settings"),    ReadOnlyAttribute(true),    DefaultValueAttribute("Welcome to your application!")]
    public string GreetingText
    {
        get { return greetingText; }
        set { greetingText = value; }
    }

    [CategoryAttribute("Global Settings"),    DefaultValueAttribute(4)]
    public int ItemsInMRUList
    {
        get { return itemsInMRU; }
        set { itemsInMRU = value; }
    }

    [DescriptionAttribute("The rate in milliseconds that the text will repeat."),    CategoryAttribute("Global Settings"),    DefaultValueAttribute(10)]
    public int MaxRepeatRate
    {
        get { return maxRepeatRate; }
        set { maxRepeatRate = value; }
    }

    [BrowsableAttribute(false),    DefaultValueAttribute(false)]
    public bool SettingsChanged
    {
        get { return settingsChanged; }
        set { settingsChanged = value; }
    }

    [CategoryAttribute("Version"),    DefaultValueAttribute("1.0"),    ReadOnlyAttribute(true)]
    public string AppVersion
    {
        get { return appVersion; }
        set { appVersion = value; }
    }
}

이러한 특성을 클래스에AppSettings 적용하여 애플리케이션을 컴파일하고 실행합니다. 다음 스크린샷은 어떻게 보이는지 보여줍니다.

그림 3. PropertyGrid에서 범주 및 기본값으로 표시되는 속성

이 버전의 옵션 창에서 작업한 후 다음과 같은 사항을 확인할 수 있습니다.

  • 속성은 SaveOnClose 창이 표시될 때 포커스를 가져옵니다.
  • MaxRepeatRate 속성을 선택하면 설명 도움말 창에 "텍스트가 반복되는 속도(밀리초)"가 표시됩니다.
  • 속성은 SaveOnClose "문서 설정" 범주 아래에 표시됩니다. 다른 속성은 "전역 설정" 및 "버전"이라는 두 가지 다른 범주 아래에 표시됩니다.
  • 속성이 SettingsChanged 더 이상 표시되지 않습니다.
  • AppVersion 속성은 읽기 전용입니다. 읽기 전용 속성은 흐리게 표시된 텍스트와 함께 표시됩니다.
  • 속성에 SaveOnClosetrue 이외의 값이 있으면 굵은 텍스트로 표시됩니다. PropertyGrid는 굵은 텍스트를 사용하여 기본값이 아닌 속성을 나타냅니다.

복합 속성 표시

지금까지 옵션 창에는 정수, 부울 및 문자열과 같은 간단한 형식이 표시되었습니다. 더 복잡한 형식은 어떨까요? 애플리케이션이 창 크기, 문서 글꼴 또는 도구 모음 색과 같은 항목을 추적해야 하는 경우 어떻게 해야 합니까? .NET Framework 제공하는 일부 데이터 형식에는 PropertyGrid에서 더 쉽게 사용할 수 있도록 하는 특수 표시 기능이 있습니다.

제공된 형식에 대한 지원

먼저 클래스를 AppSettings 업데이트하여 창 크기(크기 유형), 창 글꼴(글꼴 유형) 및 도구 모음 색( 유형)에 대한 새 속성을 추가합니다.

' Visual Basic

<DefaultPropertyAttribute("SaveOnClose")> _
Public Class AppSettings
    Private _saveOnClose As Boolean = True
    Private _greetingText As String = "Welcome to your application!"
    Private _maxRepeatRate As Integer = 10
    Private _itemsInMRU As Integer = 4

    Private _settingsChanged As Boolean = False
    Private _appVersion As String = "1.0"

    Private _windowSize As Size = New Size(100, 100)    Private _windowFont As Font = New Font("Arial", 8, FontStyle.Regular)    Private _toolbarColor As Color = SystemColors.Control

    <CategoryAttribute("Document Settings"), _
     DefaultValueAttribute(True)> _
    Public Property SaveOnClose() As Boolean
        Get
            Return _saveOnClose
        End Get
        Set(ByVal Value As Boolean)
            SaveOnClose = Value
        End Set
    End Property

    <CategoryAttribute("Document Settings")> _    Public Property WindowSize() As Size        Get            Return _windowSize        End Get        Set(ByVal Value As Size)            _windowSize = Value        End Set    End Property    <CategoryAttribute("Document Settings")> _    Public Property WindowFont() As Font        Get            Return _windowFont        End Get        Set(ByVal Value As Font)            _windowFont = Value        End Set    End Property    <CategoryAttribute("Global Settings")> _    Public Property ToolbarColor() As Color        Get            Return _toolbarColor        End Get        Set(ByVal Value As Color)            _toolbarColor = Value        End Set    End Property

    <CategoryAttribute("Global Settings"), _
    ReadOnlyAttribute(True), _
    DefaultValueAttribute("Welcome to your application!")> _
    Public Property GreetingText() As String
        Get
            Return _greetingText
        End Get
        Set(ByVal Value As String)
            _greetingText = Value
        End Set
    End Property

    <CategoryAttribute("Global Settings"), _
    DefaultValueAttribute(4)> _
    Public Property ItemsInMRUList() As Integer
        Get
            Return _itemsInMRU
        End Get
        Set(ByVal Value As Integer)
            _itemsInMRU = Value
        End Set
    End Property

    <DescriptionAttribute("The rate in milliseconds that the text will repeat."), _
    CategoryAttribute("Global Settings"), _
    DefaultValueAttribute(10)> _
    Public Property MaxRepeatRate() As Integer
        Get
            Return _maxRepeatRate
        End Get
        Set(ByVal Value As Integer)
            _maxRepeatRate = Value
        End Set
    End Property

    <BrowsableAttribute(False),
     DefaultValueAttribute(False)> _
    Public Property SettingsChanged() As Boolean
        Get
            Return _settingsChanged
        End Get
        Set(ByVal Value As Boolean)
            _settingsChanged = Value
        End Set
    End Property

    <CategoryAttribute("Version"), _
    DefaultValueAttribute("1.0"), _
    ReadOnlyAttribute(True)> _
    Public Property AppVersion() As String
        Get
            Return _appVersion
        End Get
        Set(ByVal Value As String)
            _appVersion = Value
        End Set
    End Property
End Class


//C#

[DefaultPropertyAttribute("SaveOnClose")]
public class AppSettings{
    private bool saveOnClose = true;
    private string greetingText = "Welcome to your application!";
    private int maxRepeatRate = 10;
    private int itemsInMRU = 4;

    private bool settingsChanged = false;
    private string appVersion = "1.0";
    
    private Size windowSize = new Size(100,100);    private Font windowFont = new Font("Arial", 8, FontStyle.Regular);    private Color toolbarColor = SystemColors.Control;

    [CategoryAttribute("Document Settings"),
    DefaultValueAttribute(true)]
    public bool SaveOnClose
    {
        get { return saveOnClose; }
        set { saveOnClose = value;}
    }

    [CategoryAttribute("Document Settings")]    public Size WindowSize     {        get { return windowSize; }        set { windowSize = value;}    }    [CategoryAttribute("Document Settings")]    public Font WindowFont     {        get {return windowFont; }        set { windowFont = value;}    }    [CategoryAttribute("Global Settings")]    public Color ToolbarColor    {        get { return toolbarColor; }        set { toolbarColor = value; }    }

    [CategoryAttribute("Global Settings"),
    ReadOnlyAttribute(true),
    DefaultValueAttribute("Welcome to your application!")]
    public string GreetingText
    {
        get { return greetingText; }
        set { greetingText = value; }
    }

    [CategoryAttribute("Global Settings"),
    DefaultValueAttribute(4)]
    public int ItemsInMRUList
    {
        get { return itemsInMRU; }
        set { itemsInMRU = value; }
    }

    [DescriptionAttribute("The rate in milliseconds that the text will repeat."),
    CategoryAttribute("Global Settings"),
    DefaultValueAttribute(10)]
    public int MaxRepeatRate
    {
        get { return maxRepeatRate; }
        set { maxRepeatRate = value; }
    }

    [BrowsableAttribute(false),
    DefaultValueAttribute(false)]
    public bool SettingsChanged
    {
        get { return settingsChanged; }
        set { settingsChanged = value; }
    }

    [CategoryAttribute("Version"),
    DefaultValueAttribute("1.0"),
    ReadOnlyAttribute(true)]
    public string AppVersion
    {
        get { return appVersion; }
        set { appVersion = value; }
    }
}

다음 스크린샷에서는 PropertyGrid에서 새 속성이 어떻게 표시되는지 보여 있습니다.

그림 4. PropertyGrid에 표시되는 데이터 형식 .NET Framework

속성에는 WindowFont 누를 때 글꼴 선택 대화 상자를 표시하는 줄임표("...") 단추가 있습니다. 또한 속성을 확장하여 더 많은 Font 속성을 표시할 수 있습니다. 글꼴 속성 중 일부는 글꼴에 대한 값 및 세부 정보의 드롭다운 목록을 제공합니다. WindowSize 속성을 확장하여 Size 형식의 더 많은 속성을 표시할 수 있습니다. 마지막으로 속성에 ToolbarColor 선택한 색의 견본과 다른 색을 선택하는 사용자 지정 드롭다운 목록이 있습니다. 이러한 데이터 형식 및 기타 데이터 형식의 경우 .NET Framework PropertyGrid에서 더 쉽게 편집할 수 있는 추가 클래스를 제공합니다.

사용자 지정 형식 지원

이제 클래스에 AppSettings 두 개의 속성을 더 추가합니다. 하나는 호출되고 다른 하나는 라고 DefaultFileName 합니다 SpellCheckOptions. 속성은 DefaultFileName 문자열을 가져오거나 설정하고 속성은 SpellCheckOptions 클래스의 SpellingOptions instance 가져오거나 설정합니다.

SpellingOptions 클래스는 애플리케이션의 맞춤법 검사 속성을 관리하는 새 클래스입니다. 개체의 속성을 관리하기 위해 별도의 클래스를 만들어야 하는 경우에 대한 딱딱하고 빠른 규칙은 없습니다. 전체 클래스 디자인에 따라 달라집니다. 새 파일 또는 양식의 SpellingOptions 소스 코드 아래쪽에 있는 애플리케이션 프로젝트에 클래스 정의를 추가합니다.

' Visual Basic

<DescriptionAttribute("Expand to see the spelling options for the application.")> _
Public Class SpellingOptions
    Private _spellCheckWhileTyping As Boolean = True
    Private _spellCheckCAPS As Boolean = False
    Private _suggestCorrections As Boolean = True

    <DefaultValueAttribute(True)> _
    Public Property SpellCheckWhileTyping() As Boolean
        Get
            Return _spellCheckWhileTyping
        End Get
        Set(ByVal Value As Boolean)
            _spellCheckWhileTyping = Value
        End Set
    End Property

    <DefaultValueAttribute(False)> _
    Public Property SpellCheckCAPS() As Boolean
        Get
            Return _spellCheckCAPS
        End Get
        Set(ByVal Value As Boolean)
            _spellCheckCAPS = Value
        End Set
    End Property

    <DefaultValueAttribute(True)> _
    Public Property SuggestCorrections() As Boolean
        Get
            Return _suggestCorrections
        End Get
        Set(ByVal Value As Boolean)
            _suggestCorrections = Value
        End Set
    End Property
End Class


//C#

[DescriptionAttribute("Expand to see the spelling options for the application.")]
public class SpellingOptions{
    private bool spellCheckWhileTyping = true;
    private bool spellCheckCAPS = false;
    private bool suggestCorrections = true;

    [DefaultValueAttribute(true)]
    public bool SpellCheckWhileTyping 
    {
        get { return spellCheckWhileTyping; }
        set { spellCheckWhileTyping = value; }
    }

    [DefaultValueAttribute(false)]
    public bool SpellCheckCAPS 
    {
        get { return spellCheckCAPS; }
        set { spellCheckCAPS = value; }
    }
    [DefaultValueAttribute(true)]
    public bool SuggestCorrections 
    {
        get { return suggestCorrections; }
        set { suggestCorrections = value; }
    }
}

옵션 창 애플리케이션을 다시 컴파일하고 실행합니다. 다음 스크린샷은 모양이 어떻게 표시되어야 하는지 보여줍니다.

그림 5. PropertyGrid에 표시된 형식 변환기가 없는 사용자 지정 데이터 형식

속성이 SpellcheckOptions 어떻게 표시되는지 확인합니다. .NET Framework 형식과 달리 사용자 지정 문자열 표현을 확장하거나 표시하지 않습니다. .NET Framework 형식이 고유한 복합 형식과 동일한 편집 환경을 제공하려면 어떻게 해야 할까요? .NET Framework 형식은 TypeConverterUITypeEditor 클래스를 사용하여 대부분의 PropertyGrid 편집 지원을 제공하며 이 클래스도 사용할 수 있습니다.

확장 가능한 속성 지원 추가

PropertyGrid를 가져와 속성을 확장 SpellingOptions 하려면 TypeConverter를 만들어야 합니다. TypeConverter는 한 형식에서 다른 형식으로 변환하는 방법을 제공합니다. PropertyGridTypeConverter를 사용하여 개체 형식을 String으로 변환합니다. 이 형식은 를 사용하여 개체 값을 표에 표시합니다. 편집하는 동안 TypeConverterString에서 개체 형식으로 다시 변환합니다. 이 .NET Framework 쉽게 만들 수 있도록 ExpandableObjectConverter 클래스를 제공합니다.

확장 가능한 개체 지원을 제공하려면

  1. ExpandableObjectConverter에서 상속되는 클래스를 만듭니다.

    ' Visual Basic
    
    Public Class SpellingOptionsConverter
        Inherits ExpandableObjectConverter
    End Class
    
    
    //C#
    
    public class SpellingOptionsConverter:ExpandableObjectConverter 
    {  }
    
  2. CanConvertTo 메서드를 재정의하고 매개 변수가 이 형식 변환기(예제의 클래스)SpellingOptions를 사용하는 클래스와 동일한 형식이면 destinationTypetrue를 반환합니다. 그렇지 않으면 기본 클래스 CanConvertTo 메서드의 값을 반환합니다.

    ' Visual Basic
    
    Public Overloads Overrides Function CanConvertTo( _
                                  ByVal context As ITypeDescriptorContext, _
                                  ByVal destinationType As Type) As Boolean
        If (destinationType Is GetType(SpellingOptions)) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, destinationType)
    End Function
    
    //C#
    
    public override bool CanConvertTo(ITypeDescriptorContext context,
                                      System.Type destinationType) 
    {
        if (destinationType == typeof(SpellingOptions))
            return true;
    
        return base.CanConvertTo(context, destinationType);
    }
    
  3. ConvertTo 메서드를 재정의하고 매개 변수가 destinationTypeString이고 값이 이 형식 변환기(SpellingOptions예제의 클래스)를 사용하는 클래스와 동일한 형식인지 확인합니다. 두 경우 중 하나가 false이면 기본 클래스 ConvertTo 메서드의 값을 반환합니다. 그렇지 않으면 값 개체의 문자열 표현을 반환합니다. 문자열 표현은 클래스의 각 속성을 고유한 구분 기호로 구분해야 합니다. 전체 문자열이 PropertyGrid 에 표시되므로 가독성을 손상시키지 않는 구분 기호를 선택하려고 합니다. 쉼표는 일반적으로 잘 작동합니다.

    ' Visual Basic
    
    Public Overloads Overrides Function ConvertTo( _
                                  ByVal context As ITypeDescriptorContext, _
                                  ByVal culture As CultureInfo, _
                                  ByVal value As Object, _
                                  ByVal destinationType As System.Type) _
                         As Object
        If (destinationType Is GetType(System.String) _
            AndAlso TypeOf value Is SpellingOptions) Then
    
            Dim so As SpellingOptions = CType(value, SpellingOptions)
    
            Return "Check while typing: " & so.SpellCheckWhileTyping & _
                   ", check CAPS: " & so.SpellCheckCAPS & _
                   ", suggest corrections: " & so.SuggestCorrections
        End If
        Return MyBase.ConvertTo(context, culture, value, destinationType)
    End Function
    
    //C#
    
    public override object ConvertTo(ITypeDescriptorContext context,
                                   CultureInfo culture, 
                                   object value, 
                                   System.Type destinationType) 
    {
        if (destinationType == typeof(System.String) && 
             value is SpellingOptions){
    
            SpellingOptions so = (SpellingOptions)value;
    
            return "Check while typing:" + so.SpellCheckWhileTyping + 
                   ", check CAPS: " + so.SpellCheckCAPS +
                   ", suggest corrections: " + so.SuggestCorrections;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
    
  4. (선택 사항) 형식 변환기가 문자열에서 변환할 수 있도록 지정하여 그리드에서 개체의 문자열 표현을 편집할 수 있습니다. 이렇게 하려면 먼저 CanConvertFrom 메서드를 재정의하고 원본 Type 매개 변수가 String 형식이면 true를 반환합니다. 그렇지 않으면 기본 클래스 CanConvertFrom 메서드의 값을 반환합니다.

    ' Visual Basic
    
    Public Overloads Overrides Function CanConvertFrom( _
                               ByVal context As ITypeDescriptorContext, _
                               ByVal sourceType As System.Type) As Boolean
        If (sourceType Is GetType(String)) Then
            Return True
        End If
        Return MyBase.CanConvertFrom(context, sourceType)
    End Function
    
    //C#
    
    public override bool CanConvertFrom(ITypeDescriptorContext context,
                                  System.Type sourceType) 
    {
        if (sourceType == typeof(string))
            return true;
    
        return base.CanConvertFrom(context, sourceType);
    }
    
  5. 개체의 기본 클래스를 편집할 수 있도록 하려면 ConvertFrom 메서드를 재정의하고 값 매개 변수가 String인지 확인해야 합니다. String이 아닌 경우 기본 클래스 ConvertFrom 메서드의 값을 반환합니다. 그렇지 않으면 값 매개 변수를 기반으로 클래스의 새 instance(SpellingOptions예제의 클래스)를 반환합니다. 값 매개 변수에서 클래스의 각 속성에 대한 값을 구문 분석해야 합니다. ConvertTo 메서드에서 만든 구분된 문자열의 형식을 알면 구문 분석을 수행하는 데 도움이 됩니다.

    ' Visual Basic
    
    Public Overloads Overrides Function ConvertFrom( _
                                  ByVal context As ITypeDescriptorContext, _
                                  ByVal culture As CultureInfo, _
                                  ByVal value As Object) As Object
    
        If (TypeOf value Is String) Then
            Try
                Dim s As String = CStr(value)
                Dim colon As Integer = s.IndexOf(":")
                Dim comma As Integer = s.IndexOf(",")
    
                If (colon <> -1 AndAlso comma <> -1) Then
                    Dim checkWhileTyping As String = s.Substring(colon + 1, _
                                                    (comma - colon - 1))
    
                    colon = s.IndexOf(":", comma + 1)
                    comma = s.IndexOf(",", comma + 1)
    
                    Dim checkCaps As String = s.Substring(colon + 1, _
                                                    (comma - colon - 1))
    
                    colon = s.IndexOf(":", comma + 1)
    
                    Dim suggCorr As String = s.Substring(colon + 1)
    
                    Dim so As SpellingOptions = New SpellingOptions()
    
                    so.SpellCheckWhileTyping = Boolean.Parse(checkWhileTyping)
                    so.SpellCheckCAPS = Boolean.Parse(checkCaps)
                    so.SuggestCorrections = Boolean.Parse(suggCorr)
    
                    Return so
                End If
            Catch
                Throw New ArgumentException( _
                    "Can not convert '" & CStr(value) & _ 
                                      "' to type SpellingOptions")
    
            End Try
        End If
        Return MyBase.ConvertFrom(context, culture, value)
    End Function
    
    //C#
    
    public override object ConvertFrom(ITypeDescriptorContext context,
                                  CultureInfo culture, object value) 
    {
        if (value is string) {
            try {
                string s = (string) value;
                int colon = s.IndexOf(':');
                int comma = s.IndexOf(',');
    
                if (colon != -1 && comma != -1) {
                    string checkWhileTyping = s.Substring(colon + 1 ,
                                                    (comma - colon - 1));
    
                    colon = s.IndexOf(':', comma + 1);
                    comma = s.IndexOf(',', comma + 1);
    
                    string checkCaps = s.Substring(colon + 1 , 
                                                    (comma - colon -1));
    
                    colon = s.IndexOf(':', comma + 1);
    
                    string suggCorr = s.Substring(colon + 1);
    
                    SpellingOptions so = new SpellingOptions();
    
                    so.SpellCheckWhileTyping =Boolean.Parse(checkWhileTyping);
                    so.SpellCheckCAPS = Boolean.Parse(checkCaps);
                    so.SuggestCorrections = Boolean.Parse(suggCorr);
    
                    return so;
                }
            }
            catch {
                throw new ArgumentException(
                    "Can not convert '" + (string)value + 
                                       "' to type SpellingOptions");
            }
        }  
        return base.ConvertFrom(context, culture, value);
    }
    
  6. 이제 형식 변환기 클래스가 있으므로 사용할 대상 클래스를 식별해야 합니다. TypeConverterAttribute를 대상 클래스(예제의 SpellingOptions 클래스)에 적용하여 이 작업을 수행합니다.

    ' Visual Basic
    
    ' The TypeConverter attribute applied to the SpellingOptions class.
    <TypeConverter(GetType(SpellingOptionsConverter)), _
    DescriptionAttribute("Expand to see the spelling options for the application.")> _
    Public Class SpellingOptions
       ...
    End Class
    
    
    //C#
    
    // The TypeConverter attribute applied to the SpellingOptions class.
     [TypeConverterAttribute(typeof(SpellingOptionsConverter)),
    DescriptionAttribute("Expand to see the spelling options for the application.")]
    public class SpellingOptions{ ... }
    

옵션 창 애플리케이션을 다시 컴파일하고 실행합니다. 다음 스크린샷은 이제 옵션 창이 어떻게 표시되는지 보여줍니다.

그림 6. PropertyGrid에 표시된 형식 변환기가 있는 사용자 지정 데이터 형식

**참고 ** 확장 가능한 개체만 지원하지만 사용자 지정 문자열 표현은 지원하지 않으려면 TypeConverterAttribute 를 클래스에 적용하기만 하면 됩니다. ExpandableObjectConverter를 형식 변환기 형식으로 지정합니다.

도메인 목록 및 간단한 드롭다운 속성 지원 추가

거형 형식을 기반으로 열거형을 반환하는 속성의 경우 PropertyGrid는 드롭다운 목록에 열거형 값을 자동으로 표시합니다. EnumConverter는 이 기능도 제공합니다. 속성을 소유하는 경우 열거형을 기반으로 하지 않는 형식을 사용하여 선택 목록 또는 도메인 목록이라고도 하는 유효한 값 목록을 사용자에게 제공할 수 있습니다. 런타임까지 도메인 값을 알 수 없거나 값이 변경될 수 있는 경우입니다.

옵션 창을 수정하여 사용자가 선택할 수 있는 기본 파일 이름의 도메인 목록을 제공합니다. 클래스에 DefaultFileName 속성을 이미 추가했습니다 AppSettings . 다음 단계는 도메인 목록을 제공하기 위해 PropertyGrid에서 속성에 대한 드롭다운을 표시하는 것입니다.

간단한 드롭다운 속성 지원을 제공하려면

  1. 형식 변환기 클래스에서 상속되는 클래스를 만듭니다. 속성은 DefaultFileNameString 형식이므로 StringConverter에서 상속할 수 있습니다. 속성 형식에 대한 형식 변환기가 없는 경우 TypeConverter에서 상속할 수 있습니다. 이 경우 필요하지 않습니다.

    ' Visual Basic
    
    Public Class FileNameConverter
        Inherits StringConverter
    End Class
    
    
    //C#
    
    public class FileNameConverter: StringConverter 
    {  } 
    
  2. GetStandardValuesSupported 메서드를 재정의하고 true를 반환하여 이 개체가 목록에서 선택할 수 있는 표준 값 집합을 지원함을 나타냅니다.

    ' Visual Basic
    
    Public Overloads Overrides Function GetStandardValuesSupported( _
                        ByVal context As ITypeDescriptorContext) As Boolean
        Return True
    End Function
    
    
    //C#
    
    public override bool GetStandardValuesSupported(
                               ITypeDescriptorContext context) 
    {
        return true;
    }
    
  3. GetStandardValues 메서드를 재정의하고 표준 값으로 채워진 StandardValuesCollection을 반환합니다. StandardValuesCollection을 만드는 한 가지 방법은 생성자에 값 배열을 제공하는 것입니다. 옵션 창 애플리케이션의 경우 제안된 기본 파일 이름으로 채워진 문자열 배열을 사용할 수 있습니다.

    ' Visual Basic
    
    Public Overloads Overrides Function GetStandardValues( _
                         ByVal context As ITypeDescriptorContext) _
                      As StandardValuesCollection
    
        Return New StandardValuesCollection(New String() {"New File", _
                                                          "File1", _
                                                          "Document1"})
    End Function 
    
    
    //C#
    
    public override StandardValuesCollection
                         GetStandardValues(ITypeDescriptorContext context) 
    {
        return new StandardValuesCollection(new string[]{"New File", 
                                                         "File1", 
                                                         "Document1"});
    } 
    
  4. (선택 사항) 사용자가 드롭다운 목록에 없는 값을 입력하려면 GetStandardValuesExclusive 메서드를 재정의하고 false를 반환합니다. 기본적으로 드롭다운 목록 스타일을 콤보 상자 스타일로 변경합니다.

    ' Visual Basic
    
    Public Overloads Overrides Function GetStandardValuesExclusive( _
                   ByVal context As ITypeDescriptorContext) As Boolean
        Return False
    End Function
    
    
    //C#
    
    public override bool GetStandardValuesExclusive(
                               ITypeDescriptorContext context) 
    {
        return false;
    }
    
  5. 드롭다운 목록을 표시하기 위한 고유한 형식 변환기 클래스가 있으므로 사용할 대상을 식별해야 합니다. 이 경우 형식 변환기는 속성과 DefaultFileName 관련이 있으므로 대상은 속성입니다. Target 속성에 TypeConverterAttribute 를 적용합니다.

    ' Visual Basic
    
    ' The TypeConverter attribute applied to the DefaultFileName property.
    <TypeConverter(GetType(FileNameConverter)),_
     CategoryAttribute("Document Settings")> _
    Public Property DefaultFileName() As String
        Get
            Return _defaultFileName
        End Get
        Set(ByVal Value As String)
            _defaultFileName = Value
        End Set
    End Property
    
    
    //C#
    
    // The TypeConverter attribute applied to the DefaultFileName property.
     [TypeConverter(typeof(FileNameConverter)),
     CategoryAttribute("Document Settings")]
    public string DefaultFileName
    {
        get{ return defaultFileName; }
        set{ defaultFileName = value; }
    }
    

옵션 창 애플리케이션을 다시 컴파일하고 실행합니다. 다음 스크린샷은 이제 옵션 창이 어떻게 표시되는지 보여줍니다. 속성이 DefaultFileName 표시되는 방식을 확인합니다.

그림 7. PropertyGrid에 드롭다운 도메인 목록 표시

속성에 대한 사용자 지정 UI 제공

앞에서 설명한 대로 .NET Framework 형식은 TypeConverterUITypeEditor 클래스(다른 클래스와 함께)를 사용하여 PropertyGrid 편집 지원을 제공합니다. 사용자 지정 형식 지원 섹션에서는 TypeConverter를 사용하여 살펴보았습니다. UITypeEditor 클래스를 사용하여 고유한 PropertyGrid 사용자 지정을 수행할 수도 있습니다.

ImageColor 클래스에 제공되는 것과 유사하게 PropertyGrid의 속성 값과 함께 작은 그래픽 표현을 제공할 수 있습니다. 사용자 지정을 위해 이 작업을 수행하려면 UITypeEditor에서 상속하고 GetPaintValueSupported 를 재정의하고 true를 반환 합니다. 다음으로 UITypeEditor.PaintValue 메서드를 재정의하고 메서드에서 PaintValueEventArgs.Graphics 매개 변수를 사용하여 그래픽을 그립니다. 마지막으로 UITypeEditor 클래스를 사용하는 클래스 또는 속성에 Editor 특성을 적용합니다.

다음 스크린샷은 결과가 어떻게 표시되는지 보여줍니다.

그림 8. PropertyGrid에서 속성에 대한 사용자 지정 그래픽 표시

Control.Dock 속성이 사용자 도킹 선택을 제공하는 데 사용하는 것과 유사한 고유한 드롭다운 목록 컨트롤을 제공할 수도 있습니다. 이렇게 하려면 UITypeEditor에서 상속하고, GetEditStyle을 재정의하고, DropDown과 같은 UITypeEditorEditStyle 열거형 값을 반환합니다. 사용자 지정 드롭다운 컨트롤은 Control 또는 Control 파생 클래스(예: UserControl)에서 상속되어야 합니다. 다음으로 UITypeEditor.EditValue 메서드를 재정의 합니다. IServiceProvider 매개 변수를 사용하여 IServiceProvider.GetService 메서드를 호출하여 IWindowsFormsEditorService instance 가져옵니다. 마지막으로 IWindowsFormsEditorService.DropDownControl 메서드를 호출하여 사용자 지정 드롭다운 목록 컨트롤을 표시합니다. UITypeEditor 클래스를 사용하는 클래스 또는 속성에 Editor 특성을 적용해야 합니다.

다음 스크린샷은 결과가 어떻게 표시되는지 보여줍니다.

그림 9. PropertyGrid에서 속성에 대한 사용자 지정 드롭다운 컨트롤 표시

TypeEditorUITypeEditor 클래스를 사용하는 것 외에도 PropertyGrid를 사용자 지정하여 추가 속성 탭을 표시할 수도 있습니다. 속성 탭은 PropertyTab 클래스에서 상속됩니다. Microsoft Visual C# ™ .NET에서 속성 브라우저를 사용한 경우 사용자 지정 PropertyTab 이 표시되었을 수 있습니다. 이벤트 탭(번개가 있는 단추)은 사용자 지정 PropertyTab입니다. 다음 스크린샷에서는 사용자 지정 PropertyTab 의 또 다른 예제가 아래에 나와 있습니다. 이 PropertyTab 은 단추의 경계 지점을 편집하여 사용자 지정 단추 셰이프를 만드는 기능을 제공합니다.

그림 10. PropertyGrid에 사용자 지정 탭 표시

UITypeEditor 클래스를 사용하여 PropertyGrid를 사용자 지정하는 방법에 대한 자세한 정보와 위의 사용자 지정 사용자 인터페이스, Shawn Burke의 문서인 Make Your Components Really RAD with Visual Studio .NET Property Browser의 코드 예제를 확인할 수 있습니다.

결론

.NET Framework 제공하는 ProperyGrid 컨트롤은 사용자 인터페이스를 개선하는 데 사용할 수 있는 풍부한 편집 환경을 제공합니다. PropertyGrid를 사용자 지정하는 것이 얼마나 쉬운지에 대한 새로운 지식을 통해 애플리케이션 전체에서 PropertyGrid를 사용할 수 있습니다. 또한 Visual Studio .NET 속성 브라우저는 PropertyGrid를 기반으로 하므로 이러한 기술을 사용하여 더 풍부한 디자인 타임 환경을 제공할 수 있습니다.