programing

WPF에서 콤보박스 컨트롤에 열거형을 바인드하려면 어떻게 해야 합니까?

javajsp 2023. 4. 9. 21:00

WPF에서 콤보박스 컨트롤에 열거형을 바인드하려면 어떻게 해야 합니까?

에넘이 그대로 표시되는 간단한 예를 찾고 있습니다.제가 본 예들은 모두 보기 좋은 표시 문자열을 추가하려고 하지만, 저는 그런 복잡함을 원하지 않습니다.

기본적으로 바인딩하는 모든 속성을 유지하는 클래스가 있습니다. 먼저 DataContext를 이 클래스로 설정한 다음 xaml 파일에서 다음과 같이 바인딩을 지정합니다.

<ComboBox ItemsSource="{Binding Path=EffectStyle}"/>

이 이 나와 있지 않습니다.ComboBox아이템으로서

부터 할 수 .Loaded이벤트 핸들러. §:

yourComboBox.ItemsSource = Enum.GetValues(typeof(EffectStyle)).Cast<EffectStyle>();

가 있는 는, XAML 를 가 있습니다.ObjectDataProvider바인딩 소스로 사용할 수 있는 개체를 만들려면:

<Window x:Class="YourNamespace.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        xmlns:StyleAlias="clr-namespace:Motion.VideoEffects">
    <Window.Resources>
        <ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues"
                            ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="StyleAlias:EffectStyle"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnum}}"
                  SelectedItem="{Binding Path=CurrentEffectStyle}" />
    </Grid>
</Window>

다음 코드에 주목합니다.

xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:StyleAlias="clr-namespace:Motion.VideoEffects"

MSDN에서 읽을 수 있는 이름 공간 및 어셈블리를 매핑하는 방법을 안내합니다.

가 묶는 이 나의 사물에 을 좋아한다.ViewModel 피하려고요.<ObjectDataProvider>XAML입니다.

이 솔루션에서는 View에 정의된 데이터와 코드 배후에 있는 데이터를 사용하지 않습니다.DataBinding, 재사용 가능한 ValueConverter, Enum 유형에 대한 설명 컬렉션을 가져오는 메서드 및 바인딩할 ViewModel의 단일 속성만 해당됩니다.

「 」를 바인드 Enum a까지ComboBox하지 않습니다.Enum ' ' '를 [Description()]로부터)System.ComponentModelComboBox요일 일람표를 작성하면 다음과 같습니다.

public enum DayOfWeek
{
  // add an optional blank value for default/no selection
  [Description("")]
  NOT_SET = 0,
  [Description("Sunday")]
  SUNDAY,
  [Description("Monday")]
  MONDAY,
  ...
}

먼저 에넘을 처리하는 몇 가지 방법으로 도우미 클래스를 만들었습니다.한 메서드는 특정 값에 대한 설명을 가져오고 다른 메서드는 모든 값과 유형에 대한 설명을 가져옵니다.

public static class EnumHelper
{
  public static string Description(this Enum value)
  {
    var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
    if (attributes.Any())
      return (attributes.First() as DescriptionAttribute).Description;

    // If no description is found, the least we can do is replace underscores with spaces
    // You can add your own custom default formatting logic here
    TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
    return ti.ToTitleCase(ti.ToLower(value.ToString().Replace("_", " ")));
  }

  public static IEnumerable<ValueDescription> GetAllValuesAndDescriptions(Type t)
  {
    if (!t.IsEnum)
      throw new ArgumentException($"{nameof(t)} must be an enum type");

    return Enum.GetValues(t).Cast<Enum>().Select((e) => new ValueDescription() { Value = e, Description = e.Description() }).ToList();
  }
}

다음, '하다, 하다, 하다'를 만들어요.ValueConverter에서 상속하다MarkupExtension를 사용하면 XAML에서 사용하기 쉬워지기 때문에 리소스로 선언할 필요가 없습니다.

[ValueConversion(typeof(Enum), typeof(IEnumerable<ValueDescription>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return EnumHelper.GetAllValuesAndDescriptions(value.GetType());
  }
  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return null;
  }
  public override object ProvideValue(IServiceProvider serviceProvider)
  {
    return this;
  }
}

★★★ViewModel 된다.View 수 .SelectedValue ★★★★★★★★★★★★★★★★★」ItemsSource'이것'은 다음과 같습니다.

private DayOfWeek dayOfWeek;

public DayOfWeek SelectedDay
{
  get { return dayOfWeek; }
  set
  {
    if (dayOfWeek != value)
    {
      dayOfWeek = value;
      OnPropertyChanged(nameof(SelectedDay));
    }
  }
}

그리고 마지막으로, 이 모든 것을ComboBox를 사용)ValueConverter ItemsSource★★★★★★★★★★★★★★★★★★」

<ComboBox ItemsSource="{Binding Path=SelectedDay, Converter={x:EnumToCollectionConverter}, Mode=OneTime}"
          SelectedValuePath="Value"
          DisplayMemberPath="Description"
          SelectedValue="{Binding Path=SelectedDay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

.EnumHelper 및 " " " 。EnumToCollectionConverter어떤 에넘과도 함께 일해요그리고 여기에 넣지 않았는데ValueDescription의 퍼블릭오브젝트는 class 2로 불리는 것입니다.수업Value 「」라고 불리는 것.Description 코드를 할 Tuple<object, object> ★★★★★★★★★★★★★★★★★」KeyValuePair<object, object>


「 」를에게는, 「 」를 참조해 .ValueDescription 링크:

public class ValueDescription
{
    public object Value {get; set};
    public object Description {get; set};
}

Markup Extension을 사용하여 다른 솔루션을 사용했습니다.

  1. 아이템 소스를 제공하는 클래스를 만들었습니다.

    public class EnumToItemsSource : MarkupExtension
    {
        private readonly Type _type;
    
        public EnumToItemsSource(Type type)
        {
            _type = type;
        }
    
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return Enum.GetValues(_type)
                .Cast<object>()
                .Select(e => new { Value = (int)e, DisplayName = e.ToString() });
        }
    }
    
  2. 거의 다...이제 XAML에서 사용:

        <ComboBox DisplayMemberPath="DisplayName"
              ItemsSource="{persons:EnumToItemsSource {x:Type enums:States}}"
              SelectedValue="{Binding Path=WhereEverYouWant}"
              SelectedValuePath="Value" />
    
  3. 'enums' 변경:각 주(州)에서 열거

Object Data Provider 사용:

<ObjectDataProvider x:Key="enumValues"
   MethodName="GetValues" ObjectType="{x:Type System:Enum}">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="local:ExampleEnum"/>
      </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>

다음으로 스태틱리소스에 바인드합니다.

ItemsSource="{Binding Source={StaticResource enumValues}}"

기사에 의거하여

Nick의 답변은 저에게 큰 도움이 되었습니다만, Value Description이라는 추가 수업을 피하기 위해 약간 수정될 수 있다는 것을 깨달았습니다.KeyValuePair 클래스가 프레임워크에 이미 있기 때문에 대신 사용할 수 있다는 것을 기억했습니다.

코드는 약간만 변경됩니다.

public static IEnumerable<KeyValuePair<string, string>> GetAllValuesAndDescriptions<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable
    {
        if (!typeof(TEnum).IsEnum)
        {
            throw new ArgumentException("TEnum must be an Enumeration type");
        }

        return from e in Enum.GetValues(typeof(TEnum)).Cast<Enum>()
               select new KeyValuePair<string, string>(e.ToString(),  e.Description());
    }


public IEnumerable<KeyValuePair<string, string>> PlayerClassList
{
   get
   {
       return EnumHelper.GetAllValuesAndDescriptions<PlayerClass>();
   }
}

마지막으로 XAML:

<ComboBox ItemSource="{Binding Path=PlayerClassList}"
          DisplayMemberPath="Value"
          SelectedValuePath="Key"
          SelectedValue="{Binding Path=SelectedClass}" />

이것이 다른 사람들에게 도움이 되기를 바랍니다.

시스템을 호출하여 생성할 수 있는 열거형 값의 배열을 만들어야 합니다.Enum.GetValues()를 전달하여Type이치노

「 」에 .ItemsSource모든 열거형 값으로 채워야 합니다.도 아마 묶고 예요.SelectedItem로로 합니다.EffectStyle(같은 열거형 속성으로 현재 값이 포함되어 있는 것을 확인합니다).

이 질문에는 훌륭한 답변이 많으며, 저는 겸허히 제 답변을 제출합니다.나는 내 것이 다소 단순하고 우아하다는 것을 알았다.필요한 것은 값 변환기뿐입니다.

열거가 지정되면...

public enum ImageFormat
{
    [Description("Windows Bitmap")]
    BMP,
    [Description("Graphics Interchange Format")]
    GIF,
    [Description("Joint Photographic Experts Group Format")]
    JPG,
    [Description("Portable Network Graphics Format")]
    PNG,
    [Description("Tagged Image Format")]
    TIFF,
    [Description("Windows Media Photo Format")]
    WDP
}

그리고 값 변환기...

public class ImageFormatValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ImageFormat format)
        {
            return GetString(format);
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string s)
        {
            return Enum.Parse(typeof(ImageFormat), s.Substring(0, s.IndexOf(':')));
        }
        return null;
    }

    public string[] Strings => GetStrings();

    public static string GetString(ImageFormat format)
    {
        return format.ToString() + ": " + GetDescription(format);
    }

    public static string GetDescription(ImageFormat format)
    {
        return format.GetType().GetMember(format.ToString())[0].GetCustomAttribute<DescriptionAttribute>().Description;

    }
    public static string[] GetStrings()
    {
        List<string> list = new List<string>();
        foreach (ImageFormat format in Enum.GetValues(typeof(ImageFormat)))
        {
            list.Add(GetString(format));
        }

        return list.ToArray();
    }
}

자원...

    <local:ImageFormatValueConverter x:Key="ImageFormatValueConverter"/>

XAML 선언...

    <ComboBox Grid.Row="9" ItemsSource="{Binding Source={StaticResource ImageFormatValueConverter}, Path=Strings}"
              SelectedItem="{Binding Format, Converter={StaticResource ImageFormatValueConverter}}"/>

모델 보기...

    private ImageFormat _imageFormat = ImageFormat.JPG;
    public ImageFormat Format
    {
        get => _imageFormat;
        set
        {
            if (_imageFormat != value)
            {
                _imageFormat = value;
                OnPropertyChanged();
            }
        }
    }

결과 콤보 상자...

ComboBox를 열거형으로 바인드

이치
xaml

<ComboBox ItemsSource="{Binding MyEnumArray}">

.cs

public Array MyEnumArray
{
  get { return Enum.GetValues(typeof(MyEnum)); }
}

위의 모든 게시물은 간단한 트릭을 놓쳤습니다.SelectedValue 바인딩에서 항목을 채우는 방법을 확인할 수 있습니다.XAML 마크업이 정당하도록 자동으로 소스화.

<Controls:EnumComboBox SelectedValue="{Binding Fool}"/>

예를 들어 ViewModel에는

public enum FoolEnum
    {
        AAA, BBB, CCC, DDD

    };


    FoolEnum _Fool;
    public FoolEnum Fool
    {
        get { return _Fool; }
        set { ValidateRaiseAndSetIfChanged(ref _Fool, value); }
    }

ValidateRaiseAndSetIfChanged는 INPC 후크입니다.서로 다를 수 있습니다.

EnumComboBox의 구현은 다음과 같습니다만, 우선 열거 문자열과 값을 얻으려면 약간의 도우미가 필요합니다.

    public static List<Tuple<object, string, int>> EnumToList(Type t)
    {
        return Enum
            .GetValues(t)
            .Cast<object>()
            .Select(x=>Tuple.Create(x, x.ToString(), (int)x))
            .ToList();
    }

및 메인 클래스(주의: Reactive를 사용하고 있습니다.WhenAny를 통해 속성 변경을 후크하기 위한 UI)

using ReactiveUI;
using ReactiveUI.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Windows;
using System.Windows.Documents;

namespace My.Controls
{
    public class EnumComboBox : System.Windows.Controls.ComboBox
    {
        static EnumComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(EnumComboBox), new FrameworkPropertyMetadata(typeof(EnumComboBox)));
        }

        protected override void OnInitialized( EventArgs e )
        {
            base.OnInitialized(e);

            this.WhenAnyValue(p => p.SelectedValue)
                .Where(p => p != null)
                .Select(o => o.GetType())
                .Where(t => t.IsEnum)
                .DistinctUntilChanged()
                .ObserveOn(RxApp.MainThreadScheduler)
                .Subscribe(FillItems);
        }

        private void FillItems(Type enumType)
        {
            List<KeyValuePair<object, string>> values = new List<KeyValuePair<object,string>>();

            foreach (var idx in EnumUtils.EnumToList(enumType))
            {
                values.Add(new KeyValuePair<object, string>(idx.Item1, idx.Item2));
            }

            this.ItemsSource = values.Select(o=>o.Key.ToString()).ToList();

            UpdateLayout();
            this.ItemsSource = values;
            this.DisplayMemberPath = "Value";
            this.SelectedValuePath = "Key";

        }
    }
}

또한 일반에서 유형을 올바르게 설정해야 합니다.XAML이나 당신의 상자는 아무것도 렌더링하지 않고 당신은 머리카락을 뽑을 것입니다.

<Style TargetType="{x:Type local:EnumComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
</Style>

그게 다예요.이것은 분명히 i18n을 지원하기 위해 확장될 수 있지만 투고가 길어질 것입니다.

유니버설 앱의 동작은 조금 다른 것 같습니다.풀기능의 XAML의 모든 기능을 갖추고 있는 것은 아닙니다.저에게는 다음과 같은 이점이 있습니다.

  1. 열거값 목록을 enum(문자열 또는 정수로 변환되지 않음)으로 만들고 ComboBox 항목을 바인딩했습니다.그 출처
  2. 그런 다음 ComboBox ItemSelected를 해당 열거형인 공용 속성에 바인딩할 수 있습니다.

그냥 재미삼아 이것을 돕기 위해 작은 템플릿 클래스를 만들어 MSDN 샘플 페이지에 게시했습니다.추가 비트를 사용하면 Enum의 이름을 임의로 덮어쓰고 Enum의 일부를 숨길 수 있습니다.제 코드는 제가 좀 더 일찍 봤으면 좋았을 닉의 코드(위)와 매우 흡사합니다.

샘플 실행: 열거에 대한 여러 개의 twoway 바인딩을 포함합니다.

Enum의 int 표현이 아닌 ViewModel의 실제 Enum 속성에 바인딩되어 있으면 작업이 까다로워집니다.위의 모든 예에서 예상되는 int 값이 아닌 문자열 표현에 바인드해야 한다는 것을 알게 되었습니다.

이 경우 ViewModel에서 바인딩할 속성에 단순 텍스트 상자를 바인딩하면 알 수 있습니다.텍스트가 표시되면 문자열에 바인드합니다.번호가 표시되어 있는 경우는, 그 값에 바인드 합니다.주의: Display를 두 번 사용했는데, 일반적으로는 오류가 발생하지만 이 방법밖에 없습니다.

<ComboBox SelectedValue="{Binding ElementMap.EdiDataType, Mode=TwoWay}"
                      DisplayMemberPath="Display"
                      SelectedValuePath="Display"
                      ItemsSource="{Binding Source={core:EnumToItemsSource {x:Type edi:EdiDataType}}}" />

그렉

public class EnumItemsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!value.GetType().IsEnum)
            return false;

        var enumName = value.GetType();
        var obj = Enum.Parse(enumName, value.ToString());

        return System.Convert.ToInt32(obj);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Enum.ToObject(targetType, System.Convert.ToInt32(value));
    }
}

Enum 객체 모델 속성에 직접 바인딩할 경우 이러한 Enum 값 변환기를 사용하여 Rogers 및 Greg의 답변을 확장해야 합니다.

tom.maruska의 답변은 마음에 들었지만 실행 시 템플릿에서 발생할 수 있는 열거형을 지원해야 했습니다.그러기 위해서는 마크업 확장자의 타입을 지정하기 위해 바인딩을 사용해야 했습니다.나는 니콜라이로부터 이 답변에 대해 일할 수 있었다.내가 생각할 수 있는 어떤 경우라도 효과가 있는 매우 유연한 마크업 확장자를 생각해 낼 수 있는 anykienko.다음과 같이 소비됩니다.

<ComboBox SelectedValue="{Binding MyEnumProperty}" 
          SelectedValuePath="Value"
          ItemsSource="{local:EnumToObjectArray SourceEnum={Binding MyEnumProperty}}" 
          DisplayMemberPath="DisplayName" />

위에서 언급한 매쉬업 마크업 확장 소스:

class EnumToObjectArray : MarkupExtension
{
    public BindingBase SourceEnum { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        DependencyObject targetObject;
        DependencyProperty targetProperty;

        if (target != null && target.TargetObject is DependencyObject && target.TargetProperty is DependencyProperty)
        {
            targetObject = (DependencyObject)target.TargetObject;
            targetProperty = (DependencyProperty)target.TargetProperty;
        }
        else
        {
            return this;
        }

        BindingOperations.SetBinding(targetObject, EnumToObjectArray.SourceEnumBindingSinkProperty, SourceEnum);

        var type = targetObject.GetValue(SourceEnumBindingSinkProperty).GetType();

        if (type.BaseType != typeof(System.Enum)) return this;

        return Enum.GetValues(type)
            .Cast<Enum>()
            .Select(e => new { Value=e, Name = e.ToString(), DisplayName = Description(e) });
    }

    private static DependencyProperty SourceEnumBindingSinkProperty = DependencyProperty.RegisterAttached("SourceEnumBindingSink", typeof(Enum)
                       , typeof(EnumToObjectArray), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

    /// <summary>
    /// Extension method which returns the string specified in the Description attribute, if any.  Oherwise, name is returned.
    /// </summary>
    /// <param name="value">The enum value.</param>
    /// <returns></returns>
    public static string Description(Enum value)
    {
        var attrs = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attrs.Any())
            return (attrs.First() as DescriptionAttribute).Description;

        //Fallback
        return value.ToString().Replace("_", " ");
    }
}

심플하고 알기 쉬운 설명:http://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/

xmlns:local="clr-namespace:BindingEnums"
xmlns:sys="clr-namespace:System;assembly=mscorlib"

...

<Window.Resources>
    <ObjectDataProvider x:Key="dataFromEnum" MethodName="GetValues"
                        ObjectType="{x:Type sys:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:Status"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

...

<Grid>
    <ComboBox HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="150"
              ItemsSource="{Binding Source={StaticResource dataFromEnum}}"/>
</Grid>

「」를 사용합니다.ReactiveUI다음과 같은 대체 솔루션을 만들었습니다.우아한 올인원 솔루션은 아니지만 적어도 읽을 수 있다고 생각합니다.

내 경우, 목록을 바인딩하는 것은enum컨트롤로 이행하는 경우는 드물기 때문에 코드 베이스 전체에서 솔루션을 확장할 필요가 없습니다.단, 코드를 변경하여 보다 범용적으로 만들 수 있습니다.EffectStyleLookup.Item으로Object제 코드로 테스트했습니다.다른 수정은 필요 없습니다.즉, 1개의 도우미 클래스를enum. - - 목입 list list list 。ReactiveList<EnumLookupHelper>별로 좋은 것 같지 않아요

다음 도우미 클래스 사용:

public class EffectStyleLookup
{
    public EffectStyle Item { get; set; }
    public string Display { get; set; }
}

ViewModel에서 Enum 목록을 변환하여 속성으로 표시합니다.

public ViewModel : ReactiveObject
{
  private ReactiveList<EffectStyleLookup> _effectStyles;
  public ReactiveList<EffectStyleLookup> EffectStyles
  {
    get { return _effectStyles; }
    set { this.RaiseAndSetIfChanged(ref _effectStyles, value); }
  }

  // See below for more on this
  private EffectStyle _selectedEffectStyle;
  public EffectStyle SelectedEffectStyle
  {
    get { return _selectedEffectStyle; }
    set { this.RaiseAndSetIfChanged(ref _selectedEffectStyle, value); }
  }

  public ViewModel() 
  {
    // Convert a list of enums into a ReactiveList
    var list = (IList<EffectStyle>)Enum.GetValues(typeof(EffectStyle))
      .Select( x => new EffectStyleLookup() { 
        Item = x, 
        Display = x.ToString()
      });

    EffectStyles = new ReactiveList<EffectStyle>( list );
  }
}

서서 ComboBox을합니다.SelectedValuePathenum 추가:

<ComboBox Name="EffectStyle" DisplayMemberPath="Display" SelectedValuePath="Item" />

수 .enumSelectedEffectStyle[ ViewModel ] [를 합니다.ToString()의 값ComboBox:

this.WhenActivated( d =>
{
  d( this.OneWayBind(ViewModel, vm => vm.EffectStyles, v => v.EffectStyle.ItemsSource) );
  d( this.Bind(ViewModel, vm => vm.SelectedEffectStyle, v => v.EffectStyle.SelectedValue) );
});

코멘트를 추가합니다(비록 VB에서는 이 개념을 C#으로 쉽게 복제할 수 있습니다).왜냐하면 이 내용을 참조할 필요가 있었고 답변이 너무 복잡해서 마음에 들지 않았기 때문입니다.이렇게 어려울 필요는 없어요.

그래서 좀 더 쉬운 방법이 생각났어요.열거자를 사전에 바인딩합니다.그 사전을 콤보박스에 바인드합니다.

내 콤보 상자:

<ComboBox x:Name="cmbRole" VerticalAlignment="Stretch" IsEditable="False" Padding="2" 
    Margin="0" FontSize="11" HorizontalAlignment="Stretch" TabIndex="104" 
    SelectedValuePath="Key" DisplayMemberPath="Value" />

내 코드 비하인드.이게 다른 사람에게 도움이 됐으면 좋겠어요.

Dim tDict As New Dictionary(Of Integer, String)
Dim types = [Enum].GetValues(GetType(Helper.Enumerators.AllowedType))
For Each x As Helper.Enumerators.AllowedType In types
    Dim z = x.ToString()
    Dim y = CInt(x)
    tDict.Add(y, z)
Next

cmbRole.ClearValue(ItemsControl.ItemsSourceProperty)
cmbRole.ItemsSource = tDict

이것을 그대로 실장하는 것은 추천하지 않지만, 이것이 좋은 해결책에 영감을 줄 수 있기를 바랍니다.

당신의 열거형이 Foo라고 칩시다.그러면 이런 거 하면 돼요.

public class FooViewModel : ViewModel
{
    private int _fooValue;

    public int FooValue
    {
        get => _fooValue;
        set
        {
            _fooValue = value;
            OnPropertyChange();
            OnPropertyChange(nameof(Foo));
            OnPropertyChange(nameof(FooName));
        }
    }
    public Foo Foo 
    { 
        get => (Foo)FooValue; 
        set 
        { 
            _fooValue = (int)value;
            OnPropertyChange();
            OnPropertyChange(nameof(FooValue));
            OnPropertyChange(nameof(FooName));
        } 
    }
    public string FooName { get => Enum.GetName(typeof(Foo), Foo); }

    public FooViewModel(Foo foo)
    {
        Foo = foo;
    }
}

★★★★★★★★★★★★★★★★★.Window.Load 을 Enum에 할 수 있는 ObservableCollection<FooViewModel>Data Context를 사용합니다.

난 그냥 단순하게 했을 뿐이야.ViewModel에서 열거 값을 사용하여 항목 목록을 만들었습니다.

public enum InputsOutputsBoth
{
    Inputs,
    Outputs,
    Both
}

private IList<InputsOutputsBoth> _ioTypes = new List<InputsOutputsBoth>() 
{ 
    InputsOutputsBoth.Both, 
    InputsOutputsBoth.Inputs, 
    InputsOutputsBoth.Outputs 
};

public IEnumerable<InputsOutputsBoth> IoTypes
{
    get { return _ioTypes; }
    set { }
}

private InputsOutputsBoth _selectedIoType;

public InputsOutputsBoth SelectedIoType
{
    get { return _selectedIoType; }
    set
    {
        _selectedIoType = value;
        OnPropertyChanged("SelectedIoType");
        OnSelectionChanged();
    }
}

내 xaml 코드에서는 다음 것만 필요합니다.

<ComboBox ItemsSource="{Binding IoTypes}" SelectedItem="{Binding SelectedIoType, Mode=TwoWay}">
<Window.Resources>
        <ObjectDataProvider x:Key="DiaryTypeEnum"
       MethodName="GetValues" ObjectType="{x:Type System:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="z:Enums+DiaryType"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
</Window.Resources>
...
<ComboBox ItemsSource="{Binding Source={StaticResource DiaryTypeEnum}}" SelectedItem="{x:Static z:Enums+DiaryType.Defect}" />

여기서 z xmlns:z="clr-namespace:ProjName.Helpers"

정적 클래스에 대한 My Enum

  public static class Enums
    {
        public enum DiaryType
        {
            State,
            Defect,
            Service,
            Other
        }
        public enum OtherEnumOrMethods
        {
           //TODO
        }
    }

Nick의 솔루션은 보다 심플하게 할 수 있습니다.단일 컨버터만 있으면 됩니다.

[ValueConversion(typeof(Enum), typeof(IEnumerable<Enum>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var r = Enum.GetValues(value.GetType());
        return r;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

그런 다음 콤보 박스를 표시하는 모든 장소에서 이 기능을 사용합니다.

<ComboBox ItemsSource="{Binding PagePosition, Converter={converter:EnumToCollectionConverter}, Mode=OneTime}"  SelectedItem="{Binding PagePosition}" />

여기 저의 짧은 답변이 있습니다.

public enum Direction { Left, Right, Up, Down };
public class Program
{
    public Direction ScrollingDirection { get; set; }
    public List<string> Directions { get; } = new List<string>();

    public Program()
    {
        loadListDirection();
    }

    private void loadListDirection()
    {
        Directions.AddRange(Enum.GetNames(typeof(Direction)));
    }
}

그리고 Xaml:

<ComboBox SelectedIndex="0" ItemsSource="{Binding Path=Directions, Mode=OneWay}" SelectedItem="{Binding Path=ScrollingDirection, Mode=TwoWay}"/>

행운을 빕니다.

언급URL : https://stackoverflow.com/questions/6145888/how-to-bind-an-enum-to-a-combobox-control-in-wpf