bestsource

WPF의 ComboBox에 대한 열거 속성 바인딩

bestsource 2023. 4. 29. 09:33
반응형

WPF의 ComboBox에 대한 열거 속성 바인딩

다음 코드를 예로 들 수 있습니다.

public enum ExampleEnum { FooBar, BarFoo }

public class ExampleClass : INotifyPropertyChanged
{
    private ExampleEnum example;

    public ExampleEnum ExampleProperty 
    { get { return example; } { /* set and notify */; } }
}

나는 "FooBar"와 "BarFoo" 옵션을 표시하고 투웨이 모드에서 작동하도록 ExampleProperty를 ComboBox에 데이터 바인딩하기를 원합니다.최적으로 콤보박스 정의를 다음과 같이 설정합니다.

<ComboBox ItemsSource="What goes here?" SelectedItem="{Binding Path=ExampleProperty}" />

현재 콤보박스 핸들러가 있습니다.선택이 변경되고 예제 클래스가 표시됩니다.속성 바인딩을 수동으로 수행하는 내 창에 설치된 변경된 이벤트입니다.

더 나은 방법이나 일종의 규범적인 방법이 있습니까?보통 변환기를 사용하고 ComboBox에 올바른 값을 채우는 방법은 무엇입니까?저는 지금 i18n을 시작하고 싶지도 않습니다.

편집

그래서 한 가지 질문에 답했습니다.ComboBox를 올바른 값으로 채우는 방법

정적 Enum에서 ObjectDataProvider를 통해 문자열 목록으로 Enum 값을 검색합니다.GetValues 메서드:

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

항목으로 사용할 수 있습니다.내 콤보박스 소스:

<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"/>

사용자 정의 마크업 확장을 만들 수 있습니다.

사용 예:

enum Status
{
    [Description("Available.")]
    Available,
    [Description("Not here right now.")]
    Away,
    [Description("I don't have time right now.")]
    Busy
}

XAML 상단에 표시:

    xmlns:my="clr-namespace:namespace_to_enumeration_extension_class

그리고 나서...

<ComboBox 
    ItemsSource="{Binding Source={my:Enumeration {x:Type my:Status}}}" 
    DisplayMemberPath="Description" 
    SelectedValue="{Binding CurrentStatus}"  
    SelectedValuePath="Value"  /> 

그리고 실행은...

public class EnumerationExtension : MarkupExtension
  {
    private Type _enumType;


    public EnumerationExtension(Type enumType)
    {
      if (enumType == null)
        throw new ArgumentNullException("enumType");

      EnumType = enumType;
    }

    public Type EnumType
    {
      get { return _enumType; }
      private set
      {
        if (_enumType == value)
          return;

        var enumType = Nullable.GetUnderlyingType(value) ?? value;

        if (enumType.IsEnum == false)
          throw new ArgumentException("Type must be an Enum.");

        _enumType = value;
      }
    }

    public override object ProvideValue(IServiceProvider serviceProvider) // or IXamlServiceProvider for UWP and WinUI
    {
      var enumValues = Enum.GetValues(EnumType);

      return (
        from object enumValue in enumValues
        select new EnumerationMember{
          Value = enumValue,
          Description = GetDescription(enumValue)
        }).ToArray();
    }

    private string GetDescription(object enumValue)
    {
      var descriptionAttribute = EnumType
        .GetField(enumValue.ToString())
        .GetCustomAttributes(typeof (DescriptionAttribute), false)
        .FirstOrDefault() as DescriptionAttribute;


      return descriptionAttribute != null
        ? descriptionAttribute.Description
        : enumValue.ToString();
    }

    public class EnumerationMember
    {
      public string Description { get; set; }
      public object Value { get; set; }
    }
  }

뷰 모델에서 다음을 수행할 수 있습니다.

public MyEnumType SelectedMyEnumType 
{
    get { return _selectedMyEnumType; }
    set { 
            _selectedMyEnumType = value;
            OnPropertyChanged("SelectedMyEnumType");
        }
}

public IEnumerable<MyEnumType> MyEnumTypeValues
{
    get
    {
        return Enum.GetValues(typeof(MyEnumType))
            .Cast<MyEnumType>();
    }
}

에서 XAML은 다음과 .ItemSource에 .MyEnumTypeValues그리고.SelectedItem에 .SelectedMyEnumType.

<ComboBox SelectedItem="{Binding SelectedMyEnumType}" ItemsSource="{Binding MyEnumTypeValues}"></ComboBox>

UI에서 enum의 이름을 사용하지 않는 것을 선호합니다.사용자에 대해 다른 값을 사용하는 것을 선호합니다(DisplayMemberPath 경우는 SelectedValuePath) 이두은 에 할 수 있습니다 이 두 값은 다음과 같이 패킹할 수 있습니다.KeyValuePair사전에 저장되어 있습니다.

XAML

<ComboBox Name="fooBarComboBox" 
          ItemsSource="{Binding Path=ExampleEnumsWithCaptions}" 
          DisplayMemberPath="Value" 
          SelectedValuePath="Key"
          SelectedValue="{Binding Path=ExampleProperty, Mode=TwoWay}" > 

C#

public Dictionary<ExampleEnum, string> ExampleEnumsWithCaptions { get; } =
    new Dictionary<ExampleEnum, string>()
    {
        {ExampleEnum.FooBar, "Foo Bar"},
        {ExampleEnum.BarFoo, "Reversed Foo Bar"},
        //{ExampleEnum.None, "Hidden in UI"},
    };


private ExampleEnum example;
public ExampleEnum ExampleProperty
{
    get { return example; }
    set { /* set and notify */; }
}

EDIT: MVVM 패턴과 호환됩니다.

XAML 전용으로 가능한지는 모르겠지만 다음을 시도해 보세요.

코드 뒤에 있는 "typesComboBox1"에 액세스할 수 있도록 ComboBox 이름을 지정합니다.

이제 다음을 시도합니다.

typesComboBox1.ItemsSource = Enum.GetValues(typeof(ExampleEnum));

ObjectDataProvider 사용:

<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}}"

이 블로그에서 이 솔루션 찾기

geek trap에 의해 제공되었지만 지금은 삭제된 답변을 기반으로 일부 고급 기능이 없는 슬림 버전을 만들었습니다.모든 코드가 여기에 포함되어 있어 링크로트에 의해 차단되지 않고 복사 붙여넣기를 할 수 있습니다.

나는 사용합니다.System.ComponentModel.DescriptionAttribute설계 시간 설명을 위한 것입니다.만약 당신이 이 속성을 사용하는 것을 싫어한다면 당신은 당신 자신의 속성을 만들 수 있지만, 나는 이 속성을 사용하는 것이 정말로 일을 할 수 있다고 생각합니다.속성을 사용하지 않으면 이름이 코드의 열거값 이름으로 기본 설정됩니다.

public enum ExampleEnum {

  [Description("Foo Bar")]
  FooBar,

  [Description("Bar Foo")]
  BarFoo

}

항목 소스로 사용되는 클래스는 다음과 같습니다.

public class EnumItemsSource : Collection<String>, IValueConverter {

  Type type;

  IDictionary<Object, Object> valueToNameMap;

  IDictionary<Object, Object> nameToValueMap;

  public Type Type {
    get { return this.type; }
    set {
      if (!value.IsEnum)
        throw new ArgumentException("Type is not an enum.", "value");
      this.type = value;
      Initialize();
    }
  }

  public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture) {
    return this.valueToNameMap[value];
  }

  public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture) {
    return this.nameToValueMap[value];
  }

  void Initialize() {
    this.valueToNameMap = this.type
      .GetFields(BindingFlags.Static | BindingFlags.Public)
      .ToDictionary(fi => fi.GetValue(null), GetDescription);
    this.nameToValueMap = this.valueToNameMap
      .ToDictionary(kvp => kvp.Value, kvp => kvp.Key);
    Clear();
    foreach (String name in this.nameToValueMap.Keys)
      Add(name);
  }

  static Object GetDescription(FieldInfo fieldInfo) {
    var descriptionAttribute =
      (DescriptionAttribute) Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute));
    return descriptionAttribute != null ? descriptionAttribute.Description : fieldInfo.Name;
  }

}

다음과 같이 XAML에서 사용할 수 있습니다.

<Windows.Resources>
  <local:EnumItemsSource
    x:Key="ExampleEnumItemsSource"
    Type="{x:Type local:ExampleEnum}"/>
</Windows.Resources>
<ComboBox
  ItemsSource="{StaticResource ExampleEnumItemsSource}"
  SelectedValue="{Binding ExampleProperty, Converter={StaticResource ExampleEnumItemsSource}}"/> 

내가 가장 좋아하는 방법은 다음과 같습니다.ValueConverter항목을 지정합니다.소스 및 선택한 값이 모두 동일한 속성에 바인딩됩니다.이렇게 하면 View Model을 깨끗하고 양호하게 유지하기 위한 추가 속성이 필요하지 않습니다.

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

변환기의 정의는 다음과 같습니다.

public static class EnumHelper
{
  public static string Description(this Enum e)
  {
    return (e.GetType()
             .GetField(e.ToString())
             .GetCustomAttributes(typeof(DescriptionAttribute), false)
             .FirstOrDefault() as DescriptionAttribute)?.Description ?? e.ToString();
  }
}

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

이 변환기는 모든 열거형에서 작동합니다. ValueDescription가 있는 간단한 수업입니다.Value과 재산Description소유물.당신은 그저 쉽게 사용할 수 있습니다.Tuple와 함께Item1그리고.Item2 는또.KeyValuePair와 함께Key그리고.Value값 및 설명 또는 선택한 다른 클래스 대신 해당 열거형 값의 열거형 값 및 문자열 설명을 유지할 수 있습니다.

다음과 같은 것을 고려할 수 있습니다.

  1. 텍스트 블록 또는 열거형을 표시하는 데 사용할 다른 컨트롤에 대한 스타일을 정의합니다.

    <Style x:Key="enumStyle" TargetType="{x:Type TextBlock}">
        <Setter Property="Text" Value="&lt;NULL&gt;"/>
        <Style.Triggers>
            <Trigger Property="Tag">
                <Trigger.Value>
                    <proj:YourEnum>Value1<proj:YourEnum>
                </Trigger.Value>
                <Setter Property="Text" Value="{DynamicResource yourFriendlyValue1}"/>
            </Trigger>
            <!-- add more triggers here to reflect your enum -->
        </Style.Triggers>
    </Style>
    
  2. ComboBoxItem에 대한 스타일 정의

    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock Tag="{Binding}" Style="{StaticResource enumStyle}"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
  3. 콤보 상자를 추가하고 열거형 값과 함께 로드합니다.

    <ComboBox SelectedValue="{Binding Path=your property goes here}" SelectedValuePath="Content">
        <ComboBox.Items>
            <ComboBoxItem>
                <proj:YourEnum>Value1</proj:YourEnum>
            </ComboBoxItem>
        </ComboBox.Items>
    </ComboBox>
    

열거형이 크면 많은 타이핑을 생략하고 코드에서도 동일한 작업을 수행할 수 있습니다.모든 템플릿을 한 번 정의한 다음 문자열 리소스 파일만 업데이트하기 때문에 현지화가 용이합니다.

도우미 방법을 사용하는 일반 솔루션은 다음과 같습니다.또한 기본 유형(바이트, 바이트, uint, long 등)의 열거형도 처리할 수 있습니다.

도우미 방법:

static IEnumerable<object> GetEnum<T>() {
    var type    = typeof(T);
    var names   = Enum.GetNames(type);
    var values  = Enum.GetValues(type);
    var pairs   =
        Enumerable.Range(0, names.Length)
        .Select(i => new {
                Name    = names.GetValue(i)
            ,   Value   = values.GetValue(i) })
        .OrderBy(pair => pair.Name);
    return pairs;
}//method

모델 보기:

public IEnumerable<object> EnumSearchTypes {
    get {
        return GetEnum<SearchTypes>();
    }
}//property

콤보 상자:

<ComboBox
    SelectedValue       ="{Binding SearchType}"
    ItemsSource         ="{Binding EnumSearchTypes}"
    DisplayMemberPath   ="Name"
    SelectedValuePath   ="Value"
/>

MVVM을 사용하는 경우 @rudigrobler 응답을 기반으로 다음을 수행할 수 있습니다.

ViewModel 클래스에 다음 속성 추가

public Array ExampleEnumValues => Enum.GetValues(typeof(ExampleEnum));

그런 다음 XAML에서 다음을 수행합니다.

<ComboBox ItemsSource="{Binding ExampleEnumValues}" ... />

이 가장 문제에 이에게 고통입니다.즉, ▁and▁it▁a▁:▁theity▁overlyn▁of▁to▁problems▁(▁to▁all▁how▁implement▁complex일▁complic고▁overhead안standard모▁a것지▁solutionsated'다운▁certain러▁the▁for▁most▁see니입스에▁pain나게두통patter▁trivialMarkupExtension특히 열거형 값을 속성으로 장식하는 것은 피해야 합니다.데이터 모델을 구현하기만 하면 됩니다.

일반적으로 열거값 이름을 사용자에게 표시하는 것은 좋지 않습니다.열거는 UI에 표시되지 않습니다.이러한 상수는 프로그램 컨텍스트에서 사용되는 상수입니다.값 이름은 표시를 위한 것이 아닙니다.이 단어들은 엔지니어를 지칭하기 위한 것이기 때문에 이름은 일반적으로 특별한 의미론과 어휘를 사용하며, 과학적 어휘는 대중이 이해하기 위한 것이 아닙니다.표시된 값에 대한 전용 소스를 생성하는 것을 주저하지 마십시오.

이 문제는 현지화와 관련이 있을 때 더욱 분명해집니다.
그것이 게시된 모든 답변이 단순히 지나치게 엔지니어링된 이유입니다.그들은 매우 간단한 문제를 중요한 문제처럼 보이게 합니다.
가장 사소한 해결책이 최선이라는 것은 사실입니다.원래 질문의 주제는 대부분 예외가 아닙니다.
제공된 답변에 대해 강력히 추천합니다.작동할 수도 있지만 사소한 문제에 불필요한 복잡성을 가중시킵니다.

참고로, 정적 또는 를 호출하여 항상 열거형을 값 목록 또는 값 이름 목록으로 변환할 수 있으며, 둘 다 다음을 반환합니다.IEnumerable접할당수다있에 직접 할 수 .ComboBox.ItemsSource속성(예: 데이터 바인딩을 통해).

IEnumerable<ExampleEnum> values = Enum.GetValues<ExampleEnum>();
IEnumerable<string> names = Enum.GetNames<ExampleEnum>();

일반적으로 열거형을 정의할 때 UI를 염두에 두지 않습니다.
열거 값 이름은 UI 설계 규칙에 따라 선택되지 않습니다.
일반적으로 UI 레이블과 텍스트는 개발자나 프로그래머 배경이 없는 사람들에 의해 만들어집니다.일반적으로 응용프로그램을 현지화하는 데 필요한 모든 번역을 제공합니다.
UI를 애플리케이션과 혼합하지 않는 데는 여러 가지 좋은 이유가 있습니다.
(예: 설속성이름예고을계 UI)로할 수 .DataGrid열)을 염두에 두고 있습니다.열 머리글에 공백 등을 포함할 수 있습니다.
예외 메시지가 사용자가 아닌 개발자를 대상으로 하는 것과 같은 이유입니다.특정 UI 컨텍스트에서 사용자에게 의미 있는 표시 이름을 제공하기 위해 모든 속성, 모든 예외, 열거 또는 모든 데이터 유형 또는 멤버를 속성으로 장식하고 싶지는 않습니다.
UI 디자인이 코드 기반에 포함되어 클래스를 폴링하는 것을 원하지 않습니다.
응용프로그램과 사용자 인터페이스 - 이것은 두 가지 다른 문제입니다.
이 추상 또는 가상 분리 계층을 추가하면 예를 들어 표시되지 않아야 하는 열거형 값을 추가할 수 있습니다.또는 더 일반적으로 UI를 끊거나 수정할 필요 없이 코드를 수정합니다.

속성을 사용하고 그 값을 추출하기 위해 추가 로직 로드를 구현하는 대신(반영 사용), 단순한 IValueConverter또는 이러한 표시 값을 바인딩 소스로 제공하는 전용 클래스입니다.
데이터 모델을 합니다.ComboBox으로, 목항, 가멤열버유있가속으여, 사식됩며데다니는도별이, 기서가하움자용고지를 데.ComboBox.SelectedItemEnum value"):

ExampleEnum.cs

// Define enumeration without minding any UI elements and context
public enum ExampleEnum 
{ 
    FooBar = 0, 
    BarFoo 
}

ExampleClass.cs

// Define readable enum display values in the UI context.
// Display names can come from a localizable resource.
public class BindingSource : INotifyPropertyChanged
{
    public BindingSource()
    {
        ItemModels = new List<ItemModel> 
        {
            new ItemModel { Label = "Foo Bar Display", Value = ExampleEnum.FooBar },
            new ItemModel { Label = "Bar Foo Display", Value = ExampleEnum.BarFoo }
        }
    }

    public List<ItemModel> ItemModels { get; }

    private ItemModel selectedItemModel;
    public ItemModel SelectedItemModel { get => selectedItemModel; => set and notify; }
}

ItemModel.cs

public class ItemModel
{   
    public string Label { get; set; }
    public ExampleEnum Value { get; set; }
}

주 창.xaml

<Window>
  <Window.DataContext>
    <BindingSource />
  </Window.DataContext>

  <ComboBox ItemsSource="{Binding ItemModels}"
            DisplayMemberName="DisplayValue"
            SelectedItem="{Binding SelectedItemModel}" />
</Window>

은 이은입니다.DevExpress최고의 답변을 기반으로 한 구체적인 답변Gregor S.(현재 128표).

즉, 전체 애플리케이션에서 일관된 스타일을 유지할 수 있습니다.

여기에 이미지 설명 입력

유감스럽게도 원래 답변은 다음과 같이 작동하지 않습니다.ComboBoxEdit데브익스프레스에서 제공합니다.

은 ""입니다.ComboBoxEdit:

<dxe:ComboBoxEdit ItemsSource="{Binding Source={xamlExtensions:XamlExtensionEnumDropdown {x:myEnum:EnumFilter}}}"
    SelectedItem="{Binding BrokerOrderBookingFilterSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    DisplayMember="Description"
    MinWidth="144" Margin="5" 
    HorizontalAlignment="Left"
    IsTextEditable="False"
    ValidateOnTextInput="False"
    AutoComplete="False"
    IncrementalFiltering="True"
    FilterCondition="Like"
    ImmediatePopup="True"/>

말할 것도 없이, 당신은 지적할 필요가 있을 것입니다.xamlExtensionsXAML 확장 클래스(아래에 정의됨)를 포함하는 네임스페이스:

xmlns:xamlExtensions="clr-namespace:XamlExtensions"

그리고 우리는 지적해야 합니다.myEnum열거형을 포함하는 네임스페이스:

xmlns:myEnum="clr-namespace:MyNamespace"

그런 다음, 열거형:

namespace MyNamespace
{
    public enum EnumFilter
    {
        [Description("Free as a bird")]
        Free = 0,

        [Description("I'm Somewhat Busy")]
        SomewhatBusy = 1,

        [Description("I'm Really Busy")]
        ReallyBusy = 2
    }
}

는 XAML을 수 입니다.SelectedItemValue수 부분에 , 이은세당접수근할오발때니다류킵실생를없시수문에기약의것간대터부신한에의분에당▁as실,▁of(수다니,▁part▁as▁thisbit발킵▁throws▁the생시약ter▁an▁on▁an▁oversight▁error▁unable▁set,DevExpress. 그래서 우리는 우리의 것을 수정해야 합니다.ViewModel개체에서 직접 값을 얻는 방법:

private EnumFilter _filterSelected = EnumFilter.All;
public object FilterSelected
{
    get
    {
        return (EnumFilter)_filterSelected;
    }
    set
    {
        var x = (XamlExtensionEnumDropdown.EnumerationMember)value;
        if (x != null)
        {
            _filterSelected = (EnumFilter)x.Value;
        }
        OnPropertyChanged("FilterSelected");
    }
}

완전성을 위해 원래 답변(약간 이름 변경)의 XAML 확장자는 다음과 같습니다.

namespace XamlExtensions
{
    /// <summary>
    ///     Intent: XAML markup extension to add support for enums into any dropdown box, see http://bit.ly/1g70oJy. We can name the items in the
    ///     dropdown box by using the [Description] attribute on the enum values.
    /// </summary>
    public class XamlExtensionEnumDropdown : MarkupExtension
    {
        private Type _enumType;


        public XamlExtensionEnumDropdown(Type enumType)
        {
            if (enumType == null)
            {
                throw new ArgumentNullException("enumType");
            }

            EnumType = enumType;
        }

        public Type EnumType
        {
            get { return _enumType; }
            private set
            {
                if (_enumType == value)
                {
                    return;
                }

                var enumType = Nullable.GetUnderlyingType(value) ?? value;

                if (enumType.IsEnum == false)
                {
                    throw new ArgumentException("Type must be an Enum.");
                }

                _enumType = value;
            }
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            var enumValues = Enum.GetValues(EnumType);

            return (
                from object enumValue in enumValues
                select new EnumerationMember
                       {
                           Value = enumValue,
                           Description = GetDescription(enumValue)
                       }).ToArray();
        }

        private string GetDescription(object enumValue)
        {
            var descriptionAttribute = EnumType
                .GetField(enumValue.ToString())
                .GetCustomAttributes(typeof (DescriptionAttribute), false)
                .FirstOrDefault() as DescriptionAttribute;


            return descriptionAttribute != null
                ? descriptionAttribute.Description
                : enumValue.ToString();
        }

        #region Nested type: EnumerationMember
        public class EnumerationMember
        {
            public string Description { get; set; }
            public object Value { get; set; }
        }
        #endregion
    }
}

고지 사항:저는 데브익스프레스와 관계가 없습니다.텔레릭은 또한 훌륭한 도서관입니다.

사용해 보십시오.

<ComboBox ItemsSource="{Binding Source={StaticResource ExampleEnumValues}}"
    SelectedValue="{Binding Path=ExampleProperty}" />

저는 이것을 하는 오픈 소스 CodePlex 프로젝트를 만들었습니다.여기에서 NuGet 패키지를 다운로드할 수 있습니다.

<enumComboBox:EnumComboBox EnumType="{x:Type demoApplication:Status}" SelectedValue="{Binding Status}" />

코드

    public enum RULE
    {
        [Description( "Любые, без ограничений" )]
        any,
        [Description( "Любые если будет три в ряд" )]
        anyThree,
        [Description( "Соседние, без ограничений" )]
        nearAny,
        [Description( "Соседние если будет три в ряд" )]
        nearThree
    }

    class ExtendRULE
    {
        public static object Values
        {
            get
            {
                List<object> list = new List<object>();
                foreach( RULE rule in Enum.GetValues( typeof( RULE ) ) )
                {
                    string desc = rule.GetType().GetMember( rule.ToString() )[0].GetCustomAttribute<DescriptionAttribute>().Description;
                    list.Add( new { value = rule, desc = desc } );
                }
                return list;
            }
        }
    }

XAML

<StackPanel>
   <ListBox ItemsSource= "{Binding Source={x:Static model:ExtendRULE.Values}}" DisplayMemberPath="desc" SelectedValuePath="value" SelectedValue="{Binding SelectedRule}"/>
   <ComboBox ItemsSource="{Binding Source={x:Static model:ExtendRULE.Values}}" DisplayMemberPath="desc" SelectedValuePath="value" SelectedValue="{Binding SelectedRule}"/>                        
</StackPanel>

언급URL : https://stackoverflow.com/questions/58743/databinding-an-enum-property-to-a-combobox-in-wpf

반응형