列挙体のリストを作る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