概要
UWPやWPFで列挙型から1つの値を選ぶ目的でComboBoxやListBoxを使用することはよくあります。
その場合、ItemSourceに列挙型の値のリストを入れる必要があります。
ViewModelや別リソースでそれらのリストを用意しても良いですが、どうせ全値を列挙するなら自動でやってほしい。
そこで指定した列挙型の全値を提供するMarkupExtensionを作ります。
※17/11/15追記より高度な方法として添付プロパティを利用して、SelectedItemから自動で列挙型のリストを作る方法があります。
使用方法
ComboBoxやListBoxのItemSourceに列挙型を指定したMarkupExtensionを使用します。
下記サンプルコードでは
ItemSourceにVisibility列挙型を指定しています。
さらに本題とは関係ありませんが、TextBlockのVisibilityをそのComboBoxのSelctedItemにBindしています。
ViewModelやコードビハインドは何も書いていないので省略します。
<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が表示されます。
Collapsedを選択するとTextBlockが非表示になります。
MarkupExtension実装
指定された型が列挙型の場合、GetEnumValues()
で返すだけです。
[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