Programming

열거 형을 WinForms 콤보 상자에 바인딩 한 다음 설정

procodes 2020. 7. 28. 22:08
반응형

열거 형을 WinForms 콤보 상자에 바인딩 한 다음 설정


많은 사람들이 WinForms의 콤보 상자에 열거 형을 바인딩하는 방법에 대한 질문에 대답했습니다. 이것처럼 :

comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

그러나 표시 할 실제 값을 설정할 수 없으면 상당히 쓸모가 없습니다.

나는 시도했다 :

comboBox1.SelectedItem = MyEnum.Something; // Does not work. SelectedItem remains null

나는 또한 시도했다 :

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something); // ArgumentOutOfRangeException, SelectedIndex remains -1

누구든지 이것을하는 방법에 대한 아이디어가 있습니까?


열거

public enum Status { Active = 0, Canceled = 3 }; 

드롭 다운 값 설정

cbStatus.DataSource = Enum.GetValues(typeof(Status));

선택한 항목에서 열거 형 가져 오기

Status status; 
Enum.TryParse<Status>(cbStatus.SelectedValue.ToString(), out status); 

단순화하려면 :

먼저 초기화 명령 : (예를 들어, 후 InitalizeComponent())

yourComboBox.DataSource =  Enum.GetValues(typeof(YourEnum));

콤보 박스에서 선택된 항목을 검색하려면 :

YourEnum enum = (YourEnum) yourComboBox.SelectedItem;

콤보 박스의 값을 설정하려면 다음을 수행하십시오.

yourComboBox.SelectedItem = YourEnem.Foo;

코드

comboBox1.SelectedItem = MyEnum.Something;

문제는 DataBinding에 상주해야합니다. 데이터 바인딩 할당은 생성자 다음에 발생하며 주로 콤보 박스가 처음 표시됩니다. Load 이벤트에서 값을 설정하십시오. 예를 들어 다음 코드를 추가하십시오.

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    comboBox1.SelectedItem = MyEnum.Something;
}

작동하는지 확인하십시오.


시험:

comboBox1.SelectedItem = MyEnum.Something;

EDITS :

혹시, 당신은 이미 그것을 시도했습니다. 그러나 내 comboBox가 DropDownList로 설정되었을 때 저에게 효과적이었습니다.

다음은 나를 위해 작동하는 전체 코드입니다 (DropDown 및 DropDownList 모두 사용).

public partial class Form1 : Form
{
    public enum BlahEnum
    { 
        Red,
        Green,
        Blue,
        Purple
    }

    public Form1()
    {
        InitializeComponent();

        comboBox1.DataSource = Enum.GetValues(typeof(BlahEnum));

    }

    private void button1_Click(object sender, EventArgs e)
    {
        comboBox1.SelectedItem = BlahEnum.Blue;
    }
}

다음 열거 형이 있다고 가정 해 봅시다.

public enum Numbers {Zero = 0, One, Two};

해당 값을 문자열에 매핑하는 구조체가 필요합니다.

public struct EntityName
{
    public Numbers _num;
    public string _caption;

    public EntityName(Numbers type, string caption)
    {
        _num = type;
        _caption = caption;
    }

    public Numbers GetNumber() 
    {
        return _num;
    }

    public override string ToString()
    {
        return _caption;
    }
}

이제 모든 열거 형이 문자열에 매핑 된 객체 배열을 반환하십시오.

public object[] GetNumberNameRange()
{
    return new object[]
    {
        new EntityName(Number.Zero, "Zero is chosen"),
        new EntityName(Number.One, "One is chosen"),
        new EntityName(Number.Two, "Two is chosen")
    };
}

그리고 다음을 사용하여 콤보 상자를 채우십시오.

ComboBox numberCB = new ComboBox();
numberCB.Items.AddRange(GetNumberNameRange());

열거 형을 함수에 전달하려는 경우를 대비하여 검색하는 함수를 작성하십시오.

public Numbers GetConversionType() 
{
    EntityName type = (EntityName)numberComboBox.SelectedItem;
    return type.GetNumber();           
}

그리고 당신은 확인해야합니다 :)


이 시도:

// fill list
MyEnumDropDownList.DataSource = Enum.GetValues(typeof(MyEnum));

// binding
MyEnumDropDownList.DataBindings.Add(new Binding("SelectedValue", StoreObject, "StoreObjectMyEnumField"));

StoreObject는 MyEnum 값을 저장하기위한 StoreObjectMyEnumField 속성이있는 내 개체 예입니다.


이것은 콤보 박스에 열거 형 항목을로드하는 솔루션입니다.

comboBox1.Items.AddRange( Enum.GetNames(typeof(Border3DStyle)));

그런 다음 열거 형 항목을 텍스트로 사용하십시오.

toolStripStatusLabel1.BorderStyle = (Border3DStyle)Enum.Parse(typeof(Border3DStyle),comboBox1.Text);

 public static void FillByEnumOrderByNumber<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select
                        new
                         KeyValuePair<TEnum, string>(   (enumValue), enumValue.ToString());

        ctrl.DataSource = values
            .OrderBy(x => x.Key)

            .ToList();

        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }
    public static void  FillByEnumOrderByName<TEnum>(this System.Windows.Forms.ListControl ctrl, TEnum enum1, bool showValueInDisplay = true  ) where TEnum : struct
    {
        if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj");

        var values = from TEnum enumValue in Enum.GetValues(typeof(TEnum))
                     select 
                        new 
                         KeyValuePair<TEnum,string> ( (enumValue),  enumValue.ToString()  );

        ctrl.DataSource = values
            .OrderBy(x=>x.Value)
            .ToList();

        ctrl.DisplayMember = "Value";
        ctrl.ValueMember = "Key";

        ctrl.SelectedValue = enum1;
    }

@ Amir Shenouda의 답변을 바탕으로 다음과 같이 끝납니다.

열거의 정의 :

public enum Status { Active = 0, Canceled = 3 }; 

드롭 다운 값 설정

cbStatus.DataSource = Enum.GetValues(typeof(Status));

선택한 항목에서 열거 형 가져 오기 :

Status? status = cbStatus.SelectedValue as Status?;

public Form1()
{
    InitializeComponent();
    comboBox.DataSource = EnumWithName<SearchType>.ParseEnum();
    comboBox.DisplayMember = "Name";
}

public class EnumWithName<T>
{
    public string Name { get; set; }
    public T Value { get; set; }

    public static EnumWithName<T>[] ParseEnum()
    {
        List<EnumWithName<T>> list = new List<EnumWithName<T>>();

        foreach (object o in Enum.GetValues(typeof(T)))
        {
            list.Add(new EnumWithName<T>
            {
                Name = Enum.GetName(typeof(T), o).Replace('_', ' '),
                Value = (T)o
            });
        }

        return list.ToArray();
    }
}

public enum SearchType
{
    Value_1,
    Value_2
}

    public enum Colors
    {
        Red = 10,
        Blue = 20,
        Green = 30,
        Yellow = 40,
    }

comboBox1.DataSource = Enum.GetValues(typeof(Colors));

전체 소스 ... 열거 형을 콤보 박스에 바인딩


다음 도우미 메서드를 사용하여 목록에 바인딩 할 수 있습니다.

    ''' <summary>
    ''' Returns enumeration as a sortable list.
    ''' </summary>
    ''' <param name="t">GetType(some enumeration)</param>
    Public Shared Function GetEnumAsList(ByVal t As Type) As SortedList(Of String, Integer)

        If Not t.IsEnum Then
            Throw New ArgumentException("Type is not an enumeration.")
        End If

        Dim items As New SortedList(Of String, Integer)
        Dim enumValues As Integer() = [Enum].GetValues(t)
        Dim enumNames As String() = [Enum].GetNames(t)

        For i As Integer = 0 To enumValues.GetUpperBound(0)
            items.Add(enumNames(i), enumValues(i))
        Next

        Return items

    End Function

열거 형을 문자열 목록으로 변환하고 comboBox에 추가하십시오.

comboBox1.DataSource = Enum.GetValues(typeof(SomeEnum)).Cast<SomeEnum>();

selectedItem을 사용하여 표시된 값을 설정하십시오.

comboBox1.SelectedItem = SomeEnum.SomeValue;

이것들 중 어느 것도 나를 위해 일하지는 않았지만 이것은 효과가있었습니다 (각 열거 형의 이름에 대해 더 잘 설명 할 수 있다는 이점이 있습니다). .net 업데이트 때문인지 확실하지 않지만 이것이 가장 좋은 방법이라고 생각합니다. 다음에 대한 참조를 추가해야합니다.

System.ComponentModel 사용;

enum MyEnum
{
    [Description("Red Color")]
    Red = 10,
    [Description("Blue Color")]
    Blue = 50
}

....

    private void LoadCombobox()
    {
        cmbxNewBox.DataSource = Enum.GetValues(typeof(MyEnum))
            .Cast<Enum>()
            .Select(value => new
            {
                (Attribute.GetCustomAttribute(value.GetType().GetField(value.ToString()), typeof(DescriptionAttribute)) as DescriptionAttribute).Description,
                value
            })
            .OrderBy(item => item.value)
            .ToList();
        cmbxNewBox.DisplayMember = "Description";
        cmbxNewBox.ValueMember = "value";
    }

그런 다음 데이터에 액세스하려면 다음 두 줄을 사용하십시오.

        Enum.TryParse<MyEnum>(cmbxNewBox.SelectedValue.ToString(), out MyEnum proc);
        int nValue = (int)proc;

comboBox1.SelectedItem = MyEnum.Something;

잘 작동해야합니다 ... SelectedItem인지 어떻게 알 수 있습니까?


"FindString .."함수를 사용할 수 있습니다.

Public Class Form1
    Public Enum Test
        pete
        jack
        fran
        bill
    End Enum
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.DataSource = [Enum].GetValues(GetType(Test))
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact("jack")
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact(Test.jack.ToString())
        ComboBox1.SelectedIndex = ComboBox1.FindStringExact([Enum].GetName(GetType(Test), Test.jack))
        ComboBox1.SelectedItem = Test.bill
    End Sub
End Class

KeyValuePair 값 목록을 콤보 상자의 데이터 소스로 사용할 수 있습니다. 열거 형 유형을 지정할 수있는 도우미 메서드가 필요하며 IEnumerable>을 반환합니다. 여기서 int는 enum의 값이고 string은 열거 형 값의 이름입니다. 콤보 상자에서 DisplayMember 속성을 'Key'로, ValueMember 속성을 'Value'로 설정하십시오. Value 및 Key는 KeyValuePair 구조의 공용 속성입니다. 그런 다음 SelectedItem 속성을 수행하는 것처럼 열거 형 값으로 설정하면 작동합니다.


현재 DataSource 대신 Items 속성을 사용하고 있는데, 각 열거 형 값에 대해 Add를 호출해야하지만 작은 열거 형 및 임시 코드입니다.

그런 다음 값에 대해 Convert.ToInt32를 수행하고 SelectedIndex로 설정할 수 있습니다.

임시 솔루션이지만 지금은 YAGNI입니다.

아이디어를 응원합니다. 고객 피드백을 얻은 후 적절한 버전을 사용할 때 아이디어를 사용할 것입니다.


아마도 여기에 오래된 질문이지만 문제가 있었고 해결책이 쉽고 간단했습니다 .http://www.c-sharpcorner.com/UploadFile/mahesh/1220/

데이터 바인딩을 사용하고 잘 작동하므로 확인하십시오.


comboBox1.DataSource = Enum.GetValues(typeof(MyEnum));

comboBox1.SelectedIndex = (int)MyEnum.Something;

comboBox1.SelectedIndex = Convert.ToInt32(MyEnum.Something);

이 두 가지 모두 나를 위해 다른 일이 없다고 확신합니까?


드롭 다운을위한 열거 형을 데이터 소스로 설정하는 일반적인 방법

이름이 표시됩니다. 선택된 값은 Enum 자체입니다.

public IList<KeyValuePair<string, T>> GetDataSourceFromEnum<T>() where T : struct,IConvertible
    {
        IList<KeyValuePair<string, T>> list = new BindingList<KeyValuePair<string, T>>();
        foreach (string value in Enum.GetNames(typeof(T)))
        {
            list.Add(new KeyValuePair<string, T>(value, (T)Enum.Parse(typeof(T), value)));
        }
        return list;
    }

그것은 항상 문제였습니다. 0에서 ...과 같은 정렬 된 열거 형이있는 경우 ...

public enum Test
      one
      Two
      Three
 End

.SelectedValue속성 사용 대신 콤보 상자에 이름을 바인딩 할 수 있습니다.SelectedIndex

   Combobox.DataSource = System.Enum.GetNames(GetType(test))

그리고

Dim x as byte = 0
Combobox.Selectedindex=x

프레임 워크 4에서는 다음 코드를 사용할 수 있습니다.

예를 들어 MultiColumnMode 열거 형을 콤보 박스에 바인딩하려면 :

cbMultiColumnMode.Properties.Items.AddRange(typeof(MultiColumnMode).GetEnumNames());

선택한 색인을 얻으려면 :

MultiColumnMode multiColMode = (MultiColumnMode)cbMultiColumnMode.SelectedIndex;

note: I use DevExpress combobox in this example, you can do the same in Win Form Combobox


A little late to this party ,

The SelectedValue.ToString() method should pull in the DisplayedName . However this article DataBinding Enum and also With Descriptions shows a handy way to not only have that but instead you can add a custom description attribute to the enum and use it for your displayed value if you preferred. Very simple and easy and about 15 lines or so of code (unless you count the curly braces) for everything.

It is pretty nifty code and you can make it an extension method to boot ...


only use casting this way:

if((YouEnum)ComboBoxControl.SelectedItem == YouEnum.Español)
{
   //TODO: type you code here
}

You can use a extension method

 public static void EnumForComboBox(this ComboBox comboBox, Type enumType)
 {
     var memInfo = enumType.GetMembers().Where(a => a.MemberType == MemberTypes.Field).ToList();
     comboBox.Items.Clear();
     foreach (var member in memInfo)
     {
         var myAttributes = member.GetCustomAttribute(typeof(DescriptionAttribute), false);
         var description = (DescriptionAttribute)myAttributes;
         if (description != null)
         {
             if (!string.IsNullOrEmpty(description.Description))
             {
                 comboBox.Items.Add(description.Description);
                 comboBox.SelectedIndex = 0;
                 comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
             }
         }   
     }
 }

How to use ... Declare enum

using System.ComponentModel;

public enum CalculationType
{
    [Desciption("LoaderGroup")]
    LoaderGroup,
    [Description("LadingValue")]
    LadingValue,
    [Description("PerBill")]
    PerBill
}

This method show description in Combo box items

combobox1.EnumForComboBox(typeof(CalculationType));

This is probably never going to be seen among all the other responses, but this is the code I came up with, this has the benefit of using the DescriptionAttribute if it exists, but otherwise using the name of the enum value itself.

I used a dictionary because it has a ready made key/value item pattern. A List<KeyValuePair<string,object>> would also work and without the unnecessary hashing, but a dictionary makes for cleaner code.

I get members that have a MemberType of Field and that are literal. This creates a sequence of only members that are enum values. This is robust since an enum cannot have other fields.

public static class ControlExtensions
{
    public static void BindToEnum<TEnum>(this ComboBox comboBox)
    {
        var enumType = typeof(TEnum);

        var fields = enumType.GetMembers()
                              .OfType<FieldInfo>()
                              .Where(p => p.MemberType == MemberTypes.Field)
                              .Where(p => p.IsLiteral)
                              .ToList();

        var valuesByName = new Dictionary<string, object>();

        foreach (var field in fields)
        {
            var descriptionAttribute = field.GetCustomAttribute(typeof(DescriptionAttribute), false) as DescriptionAttribute;

            var value = (int)field.GetValue(null);
            var description = string.Empty;

            if (!string.IsNullOrEmpty(descriptionAttribute?.Description))
            {
                description = descriptionAttribute.Description;
            }
            else
            {
                description = field.Name;
            }

            valuesByName[description] = value;
        }

        comboBox.DataSource = valuesByName.ToList();
        comboBox.DisplayMember = "Key";
        comboBox.ValueMember = "Value";
    }


}

참고URL : https://stackoverflow.com/questions/906899/binding-an-enum-to-a-winforms-combo-box-and-then-setting-it

반응형