簡體   English   中英

如何將枚舉綁定到 WPF 中的 combobox 控件?

[英]How to bind an enum to a combobox control in WPF?

我試圖找到一個簡單的示例,其中枚舉按原樣顯示。 我見過的所有示例都試圖添加漂亮的顯示字符串,但我不想要那種復雜性。

基本上我有一個 class 包含我綁定的所有屬性,首先將 DataContext 設置為此 class,然后在 xaml 文件中指定這樣的綁定:

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

但這並沒有將ComboBox中的枚舉值顯示為項目。

您可以通過將以下代碼放入 Window Loaded的事件處理程序中來從代碼中執行此操作,例如:

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

如果您需要在 XAML 中綁定它,您需要使用ObjectDataProvider創建 object 作為綁定源:

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

指導如何 map 命名空間和程序集,您可以在MSDN上閱讀。

我喜歡在我的ViewModel中定義我要綁定的所有對象,因此我盡量避免在 xaml 中使用<ObjectDataProvider>

我的解決方案不使用視圖中定義的數據,也不使用代碼隱藏。 只有一個 DataBinding、一個可重用的 ValueConverter、一個獲取任何 Enum 類型的描述集合的方法,以及 ViewModel 中要綁定的單個屬性。

當我想將Enum綁定到ComboBox時,我要顯示的文本永遠不會與Enum的值匹配,因此我使用[Description()]屬性為其提供我真正想在ComboBox中看到的文本。 如果我有一周中的幾天的枚舉,它看起來像這樣:

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

首先,我使用幾種處理枚舉的方法創建了助手 class。 一種方法獲取特定值的描述,另一種方法獲取類型的所有值及其描述。

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可以為 combobox 的SelectedValueItemsSource綁定的 1 個屬性:

private DayOfWeek dayOfWeek;

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

最后綁定ComboBox視圖(使用ItemsSource綁定中的ValueConverter )...

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

要實施此解決方案,您只需復制我的EnumHelper class 和EnumToCollectionConverter class。 他們將與任何枚舉一起使用。 另外,我沒有在此處包含它,但ValueDescription class 只是一個簡單的 class 具有 2 個公共 object 屬性,一個稱為Value ,一個稱為Description 您可以自己創建,也可以更改代碼以使用Tuple<object, object>KeyValuePair<object, object>

我使用了另一個使用 MarkupExtension 的解決方案。

  1. 我制作了 class ,它提供了物品來源:

     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. 將“枚舉:狀態”更改為您的枚舉

使用 ObjectDataProvider:

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

然后綁定到 static 資源:

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

根據這篇文章

尼克的回答確實幫助了我,但我意識到它可以稍微調整一下,以避免額外的 class,ValueDescription。 我記得框架中已經存在一個 KeyValuePair class,所以可以使用它來代替。

代碼僅略有變化:

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

我希望這對其他人有幫助。

您需要在枚舉中創建一個值數組,該數組可以通過調用System.Enum.GetValues()來創建,並將您想要的項目的枚舉Type傳遞給它。

如果為ItemsSource屬性指定此項,則應使用枚舉的所有值填充它。 您可能希望將SelectedItem綁定到EffectStyle (假設它是同一個枚舉的屬性,並且包含當前值)。

以上所有帖子都錯過了一個簡單的技巧。 可以從 SelectedValue 的綁定中找出如何自動填充 ItemsSource,以便您的 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();
    }

和主要的 class (注意我使用 ReactiveUI 通過 WhenAny 掛鈎屬性更改)

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

        }
    }
}

您還需要在 Generic.XAML 中正確設置樣式,否則您的盒子將不會渲染任何內容,您會將頭發拉出。

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

就是這樣。 這顯然可以擴展到支持 i18n,但會使帖子更長。

這個問題有很多很好的答案,我謙虛地提交我的。 我發現我的更簡單,更優雅。 它只需要一個值轉換器。

給定一個枚舉...

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

查看 model...

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

結果 combobox...

綁定到枚舉的組合框

通用應用程序的工作方式似乎有些不同。 它不具備全功能 XAML 的所有功能。 對我有用的是:

  1. 我創建了一個枚舉值列表作為枚舉(未轉換為字符串或整數)並將 ComboBox ItemsSource 綁定到該列表
  2. 然后我可以將 ComboBox ItemSelected 綁定到我的公共屬性,其類型是有問題的枚舉

只是為了好玩,我制作了一個小模板 class 來幫助解決這個問題,並將其發布到MSDN 示例頁面 額外的位讓我可以選擇覆蓋枚舉的名稱並讓我隱藏一些枚舉。 我的代碼看起來很像尼克的(上圖),我希望我早點看到。

運行樣本;它包括對枚舉的多個雙向綁定

如果您要綁定到 ViewModel 上的實際枚舉屬性,而不是枚舉的 int 表示,事情就會變得棘手。 我發現有必要綁定到字符串表示,而不是上面所有示例中預期的 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));
    }
}

如果您直接綁定到枚舉 object model 屬性,您應該使用這種枚舉值轉換器擴展 Rogers 和 Greg 的答案。

我喜歡tom.maruska 的回答,但我需要支持我的模板在運行時可能遇到的任何枚舉類型。 為此,我必須使用綁定來指定標記擴展的類型。 我能夠在 nicolay.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>

它工作得非常好和簡單。
xaml

<ComboBox ItemsSource="{Binding MyEnumArray}">

。CS

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

我正在添加我的評論(遺憾的是,在 VB 中,但這個概念可以很容易地在心跳中復制到 C#),因為我只需要參考這個並且不喜歡任何答案,因為它們太復雜了。 它不應該這么困難。

所以我想出了一個更簡單的方法。 將枚舉器綁定到字典。 將該字典綁定到 Combobox。

我的 combobox:

<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

使用ReactiveUI ,我創建了以下替代解決方案。 這不是一個優雅的一體化解決方案,但我認為至少它是可讀的。

在我的情況下,將enum列表綁定到控件是一種罕見的情況,因此我不需要在代碼庫中擴展解決方案。 但是,可以通過將EffectStyleLookup.Item更改為Object來使代碼更通用。 我用我的代碼測試了它,不需要其他修改。 這意味着一個助手 class 可以應用於任何enum列表。 雖然這會降低它的可讀性 - ReactiveList<EnumLookupHelper>沒有很好的影響。

使用以下幫助程序 class:

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

在 ViewModel 中,轉換枚舉列表並將其作為屬性公開:

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中,利用SelectedValuePath屬性綁定到原始enum值:

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

在視圖中,這允許我們將原始enum綁定到 ViewModel 中的SelectedEffectStyle ,但在ComboBox中顯示ToString()值:

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) );
});

尼克的解決方案可以進一步簡化,沒有什么花哨的,你只需要一個轉換器:

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

我不建議按原樣實施,但希望這可以激發一個好的解決方案。

假設您的枚舉是 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方法上,您可以將所有枚舉加載到ObservableCollection<FooViewModel>中,您可以將其設置為 combobox 的 DataContext。

我只是保持簡單。 我在 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"

我的枚舉到 static class

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

這是我的簡短回答。

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

祝你好運!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM