[WPF]enumをコンボボックスに表示する方法

enumのデータをコンボボックスに表示する方法を紹介します。

とりあえず動く状態

Dictionary型にenumの値とそれに対応する文字列を追加しています。

C#

using System.Collections.Generic;

namespace WpfApp12
{
    enum Fruits
    {
        Apple,
        Banana,
        Orange,
    }

    class MainWindowViewModel
    {
        public Dictionary<Fruits, string> FruitsEnum { get; } = new Dictionary<Fruits, string>();

        public MainWindowViewModel()
        {
            FruitsEnum.Add(Fruits.Apple, "アップル");
            FruitsEnum.Add(Fruits.Banana, "バナナ");
            FruitsEnum.Add(Fruits.Orange, "オレンジ");
        }
    }
}

DisplayMemberPathに表示するプロパティ名(Dictionary型のValue)、SelectedValuePathに選択されるプロパティ名(Dictionary型のKey)を指定しています。

Xaml

<Window x:Class="WpfApp12.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp12"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>

    <Grid>
        <ComboBox ItemsSource="{Binding FruitsEnum}" 
                  DisplayMemberPath="Value"
                  SelectedValuePath="Key"
                  />
    </Grid>
</Window>

これだと、enumの値が増えたときにコードを追加していかないといけないので拡張メソッドを利用するとそんな必要もなくなります。

拡張メソッドを利用した場合

拡張メソッドでenumの日本語の値を取得できるように変更しています。

C#

using System.Collections.Generic;

namespace WpfApp12
{
    enum Fruits
    {
        [Description("アップル")]
        Apple,
        [Description("バナナ")]
        Banana,
        [Description("オレンジ")]
        Orange,
    }

    class MainWindowViewModel
    {
        public Dictionary<Fruits, string> FruitsEnum { get; } = new Dictionary<Fruits, string>();

        public MainWindowViewModel()
        {
            foreach (var value in Enum.GetValues(typeof(Fruits)))
            {
                FruitsEnum.Add((Fruits)value, FruitsExtensions.GetName((Fruits)value));
            }
        }

    }

    static class FruitsExtensions
    {
        // 拡張メソッド
        public static string GetName<T>(this T Value)
             where T : struct, IComparable, IConvertible, IFormattable
        {
            if (!(typeof(T).IsEnum))
            {
                throw new InvalidEnumArgumentException();
            }

            var fieldInfo = Value.GetType().GetField(Value.ToString());
            if (fieldInfo == null) return null;

            var attr = (DescriptionAttribute)fieldInfo.GetCustomAttribute(typeof(DescriptionAttribute));
            if (attr == null) return "";
            return attr.Description;
        }
    }
}

以下のサイトを参考にさせてもらいました。

http://estensworks.com/devlog/2018/04/11/c%E3%81%A7enum%E5%9E%8B%E7%94%A8%E3%81%AE%E6%8B%A1%E5%BC%B5%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/

enumの値を日本語にする

これはおまけですが、enumの値を日本語にすることで拡張メソッドを使わないという方法もあります。

C#


namespace WpfApp12
{
    enum Fruits
    {
        アップル,
        バナナ,
        オレンジ,
    }

    class MainWindowViewModel
    {
        public Dictionary<Fruits, string> FruitsEnum { get; } = new Dictionary<Fruits, string>();

        public MainWindowViewModel()
        {
            foreach (var value in Enum.GetValues(typeof(Fruits)))
            {
                FruitsEnum.Add((Fruits)value, value.ToString());
            }
        }

    }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA