🍡

enum のバインド

に公開

はじめに

WinUI 3 における enum のバインドについて、状況と対策の整理です。

サンプルプログラムは GitHub に上げてあります。

動作状況

プロパティーが enum だった場合の動作ですが、片方向バインドは問題なく動作します。

MainPageViewModel.cs
public enum MyEnum
{
  Zero,
  First,
  Second,
  Third
}

internal partial class MainPageViewModel : ObservableRecipient
{
  [ObservableProperty]
  public partial MyEnum MyEnum
  {
    get;
    set;
  }
}
MainPage.xaml
<TextBlock Text="{x:Bind ViewModel.MyEnum, Mode=OneWay}" />

しかし、双方向バインドはそのままでは事実上使えません。

MainPage.xaml
<TextBox Text="{x:Bind ViewModel.MyEnum, Mode=TwoWay}" />

ビルド・実行・値の表示はできますが、ユーザーが値を変更すると(というより、フォーカスが離れるなどのトリガーがあると)例外が発生します。「Second」(enum の文字列表記)、「2」(実際の数値)いずれを入力しても例外です。

IValueConverter

双方向バインドする場合は IValueConverter でコンバーターを作成します。

TextBox にバインドしたい場合、Text プロパティーが文字列なので、enum←→文字列のコンバーターを作成します。

EnumToStringConverter.cs
internal class EnumToStringConverter : IValueConverter
{
  /// <summary>
  /// enum → String
  /// </summary>
  public Object Convert(Object value, Type targetType, Object parameter, String language)
  {
    return ((MyEnum)value).ToString();
  }

  /// <summary>
  /// String(大文字小文字を区別しない)→ enum
  /// </summary>
  public Object ConvertBack(Object value, Type targetType, Object parameter, String language)
  {
    if (Enum.TryParse((String)value, true, out MyEnum result))
    {
      return result;
    }
    return MyEnum.Zero;
  }
}

XAML でバインドする際、作成したコンバーターを使用します。

MainPage.xaml
<Page
  x:Class="TestEnumBinding.Views.MainWindows.MainPage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:m="using:TestEnumBinding.Models"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Background="{ThemeResource SolidBackgroundFillColorBaseBrush}"
  mc:Ignorable="d">

  <Page.Resources>
    <m:EnumToStringConverter x:Key="EnumToStringConverter"/>
  </Page.Resources>

  <StackPanel Orientation="Horizontal" Margin="20" >
    <TextBox Text="{x:Bind ViewModel.MyEnum, Mode=TwoWay, Converter={StaticResource EnumToStringConverter}}" />
  </StackPanel>
</Page>

「Second」、「2」、どちらでも入力できるようになります。

ComboBox

ComboBox その 1

ComboBox で enum を選択させたい場合、ItemsSource が enum 配列の場合はシンプルです。

EnumToStringConverter.cs
internal partial class MainPageViewModel : ObservableRecipient
{
  public MainPageViewModel()
  {
    MyEnumValues = (MyEnum[])Enum.GetValues(typeof(MyEnum));
  }

  public MyEnum[] MyEnumValues
  {
    get;
  }

  [ObservableProperty]
  public partial MyEnum MyEnum
  {
    get;
    set;
  }
}

XAML でバインドする際、SelectedItem に enum を直接バインドできます。

MainPage.xaml
<ComboBox ItemsSource="{x:Bind ViewModel.MyEnumValues}" SelectedItem="{x:Bind ViewModel.MyEnum, Mode=TwoWay}" />

ComboBox その 2

実務上は ItemsSource が enum 配列のケースは少なく、ItemsSource にはもっとわかりやすいラベル(文字列)を割り当てることが多いかと思います。

EnumToStringConverter.cs
internal partial class MainPageViewModel : ObservableRecipient
{
  public MainPageViewModel()
  {
    MyEnumLabels = ["零", "壱", "弐", "参"];
  }

  public String[] MyEnumLabels
  {
    get;
  }

  [ObservableProperty]
  public partial MyEnum MyEnum
  {
    get;
    set;
  }
}

その場合は SelectedIndexIValueConverter で対応します。SelectedIndex プロパティーが Int32 なので、enum←→Int32 のコンバーターを作成します。

EnumToInt32Converter.cs
internal class EnumToInt32Converter : IValueConverter
{
  /// <summary>
  /// enum → Int32
  /// </summary>
  public Object Convert(Object value, Type targetType, Object parameter, String language)
  {
    return (Int32)value;
  }

  /// <summary>
  /// Int32 → enum
  /// </summary>
  public Object ConvertBack(Object value, Type targetType, Object parameter, String language)
  {
    return value;
  }
}

XAML でバインドする際、作成したコンバーターを使用します。

MainPage.xaml
<ComboBox ItemsSource="{x:Bind ViewModel.MyEnumLabels}" SelectedIndex="{x:Bind ViewModel.MyEnum, Mode=TwoWay, Converter={StaticResource EnumToInt32Converter}}" />

まとめ

多くの場合、IValueConverter を使用して enum をバインドすることになるかと思います。

サンプルプログラム

サンプルプログラム(GitHub に上げてあります)を実行すると、enum バインドの動作を確認できます。

確認環境

項目 環境
OS Windows 11 Pro 25H2
Visual Studio 2026 18.5.2
.NET 10.0
Template Studio for WinUI 5.5
WinUIEx 2.9.0
Windows App SDK 2.0.1

参考リンク

Discussion