ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [C#] - WinForm PropertyGrid 에 표시되는 Enum 값 이름 변경하기
    .NET/CSharp 2018. 12. 25. 11:44

     PropertyGrid 를 활용하여 프로퍼티 설정하는 다이얼로그 창을 개발하던 중 Enum 에 해당 하는 값을 UI에 그대로 표현 하기에는 적당하지 않아 변경하는 방법을 찾아 보았다.

     

    기본적으로 PropertyGrid 에 속성을 표현하기 위해서는 SelectedObject Property를 사용한다.

     

    자세한 활용법은 MSDN을 참고하시기 바란다.

     

    MSDN PropertyGrid

    https://msdn.microsoft.com/ko-kr/library/aa302326.aspx

     

    PropertyGridForm

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Test
    {
        public partial class PropertyGridForm : Form
        {
            public PropertyGridForm()
            {
                InitializeComponent();
    
                _propertyGrid.SelectedObject = new PropertiesObject();
            }
        }
    }

     

    PropertiesObject

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Test
    {
        internal class PropertiesObject
        {
            private TestOriginEnum testOriginEnum = TestOriginEnum.Test1;
            
            public TestOriginEnum TestOriginEnum
            {
                get { return testOriginEnum; }
                set { testOriginEnum = value; }
            }
        }
    }

     

    TestOriginEnum

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Test
    {
        internal enum TestOriginEnum
        {
            Test1, Test2
        }
    }

     

    [ 그림 1 - PropertyGridForm ]

     

     해당 PropertyGridForm 을 실행 하면 그림 1과 같이 표시된다. TestOriginEnum에 정의한 Test1, Test2가 그대로 표현 되는 걸 그림 1로 통해 확인 할 수 있다.

     

    이젠 Test1 = 1, Test2 = 2 표시되게 Enum을 추가 해 보도록 하겠습니다.

     

    TestConvertEnum

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    
    namespace Test
    {
        internal enum TestConvertEnum
        {
            [Description("1")]
            Test1,
    
            [Description("2")]
            Test2
        }
    }

     기존 TestOriginEnum 과 틀린점은 Description Attribute를 정의한다는 점이 틀립니다. 이젠 해당 TestConvertEnum을 화면에 표시하기 위해 PropertiesObject에 Property를 추가합니다.

     

    PropertiesObject

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    
    namespace Test
    {
        internal class PropertiesObject
        {
            private TestOriginEnum testOriginEnum = TestOriginEnum.Test1;
            private TestConvertEnum testConvertEnum = TestConvertEnum.Test1;
    
            public TestOriginEnum TestOriginEnum
            {
                get { return testOriginEnum; }
                set { testOriginEnum = value; }
            }
    
            [TypeConverter(typeof(TestConverterEnum))]
            public TestConvertEnum TestConvertEnum
            {
                get { return testConvertEnum; }
                set { testConvertEnum = value; }
            }
        }
    }

     기존에 정의한 TestOriginEnum 과 틀린점은 [TypeConverter[typeof(TestConverterEnum))] Attribute 구문이 추가된 점입니다. 해당 선언을 통하여 화면에 표시될때 TestConvertEnum에서 정의한 Description Attribute 값을 TestConverterEnum을 통하여 한다는 점입니다.

     

    TestConverterEnum

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    
    namespace Test
    {
        class TestConverterEnum : EnumConverter
        {
            private Type enumType;
    
            public TestConverterEnum(Type type) : base(type)
            {
                enumType = type;
            }
    
            public override bool CanConvertTo(ITypeDescriptorContext context, Type destType)
            {
                return destType == typeof(string);
            }
    
            public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture,
                                             object value, Type destType)
            {
                FieldInfo fi = enumType.GetField(Enum.GetName(enumType, value));
                DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
                                            typeof(DescriptionAttribute));
                if (dna != null)
                    return dna.Description;
                else
                    return value.ToString();
            }
    
            public override bool CanConvertFrom(ITypeDescriptorContext context, Type srcType)
            {
                return srcType == typeof(string);
            }
    
            public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture,
                                               object value)
            {
                foreach (FieldInfo fi in enumType.GetFields())
                {
                    DescriptionAttribute dna = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
                                                typeof(DescriptionAttribute));
                    if ((dna != null) && ((string)value == dna.Description))
                        return Enum.Parse(enumType, fi.Name);
                }
                return Enum.Parse(enumType, (string)value);
            }
        }
    }

    EnumConverter 클래스를 상속받아 중요 메소드를 구현한 걸 보실 수 있습니다.  C#을 어느정도 하신 분이라면 대략 파악이 가능 하실 거라 생각합니다

     

    [ 그림 2 - PropertyGridForm EnumConverter 적용한 프로퍼티 ]

     

    [ 참고 ]

    https://stackoverflow.com/questions/7422685/edit-the-display-name-of-enumeration-members-in-a-propertygrid

    댓글

Designed by Tistory.