C#
.NET
WPF
VisualStudio
Xaml

列挙体のリストを作るMarkupExtension

More than 1 year has passed since last update.

概要

UWPやWPFで列挙型から1つの値を選ぶ目的でComboBoxやListBoxを使用することはよくあります。
その場合、ItemSourceに列挙型の値のリストを入れる必要があります。
ViewModelや別リソースでそれらのリストを用意しても良いですが、どうせ全値を列挙するなら自動でやってほしい。
そこで指定した列挙型の全値を提供するMarkupExtensionを作ります。

※17/11/15追記より高度な方法として添付プロパティを利用して、SelectedItemから自動で列挙型のリストを作る方法があります

使用方法

ComboBoxやListBoxのItemSourceに列挙型を指定したMarkupExtensionを使用します。

下記サンプルコードでは
ItemSourceにVisibility列挙型を指定しています。
さらに本題とは関係ありませんが、TextBlockのVisibilityをそのComboBoxのSelctedItemにBindしています。
ViewModelやコードビハインドは何も書いていないので省略します。

MainWindow.xaml
<Window
    x:Class="EnumCreateMarkupExtensionTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:EnumCreateMarkupExtensionTest"
    Width="325" Height="150">
    <StackPanel>
        <TextBlock
            Margin="10"
            Background="Red"
            Visibility="{Binding SelectedItem, ElementName=comboBox}" />
        <ComboBox x:Name="comboBox" ItemsSource="{local:EnumCreate Visibility}" />
    </StackPanel>
</Window>

実行結果

Visibleを選択するとTextBlockが表示されます。

スクリーンショット 2017-11-12 11.19.48.png

Collapsedを選択するとTextBlockが非表示になります。

スクリーンショット 2017-11-12 11.19.56.png

MarkupExtension実装

指定された型が列挙型の場合、GetEnumValues()で返すだけです。

EnumCreateExtension.cs
[MarkupExtensionReturnType(typeof(IEnumerable))]
public class EnumCreateExtension : MarkupExtension
{
    [ConstructorArgument("prefix")]
    public Type Type { get; set; }

    public EnumCreateExtension(Type type)
    {
        this.Type = type;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
        => Type.IsEnum ?
        Type.GetEnumValues() :
        null;
}

環境

VisualStudio2017
.NET Framework 4.7
C#7