0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【WPF】Converterの作成方法【C#】

Last updated at Posted at 2024-09-20

概要

WPFでよく使用するConveterクラスについて、説明とサンプルコードを簡単にまとめました。

Converterクラスとは

Converterクラスは、ViewとViewModel間で異なる型のデータを、互換性のある形式に変換する役割を果たします。たとえば、ViewModelのBool型のデータを、Viewに合わせてVisibility型に変換するConverterがあるとします。その場合、ViewModelのとあるbool型のデータがtrueなら、Viewのとあるコントロールを表示、falseならとあるコントロールを非表示、という実装ができます。
他にも、ViewModelのBool型のデータを、ViewのBrushes型 (色) に変換するConverterなら、bool型の値に合わせて、Viewのコントロールの色を変更できたりします。

作成方法

Converterクラスを作る際は、標準ライブラリPresentationFramework.dllの名前空間System.Windows.Dataにある、インターフェースIValueConverterをもつのが一般的です。Converterクラス内にはConvertメソッドとConvertBackメソッドを実装します。ConvertメソッドはViewModelのプロパティからViewへの変換を記述し、ConvertBackメソッドはViewからViewModelのプロパティへの変換を記述します。
ただConvertBackメソッドは使用しない場合も多いので、
その場合はthrow new NotImplementedException();等を記述しておきます。

サンプルコード

以下に、いくつかのConverterクラスのサンプルコードをまとめました。

1. ViewModelのbool値をViewのVisibilityに変換する

ViewModelのとあるプロパティのbool値がtrueのときはVisiblefalseのときはCollapsedに変換するクラスです。

Converter

namespace Hoge.Converters
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                if (value == null || (bool)value == false)
                {
                    return Visibility.Collapsed;
                }
                else
                {
                    return Visibility.Visible;
                }
            }
            catch (Exception)
            {
                // エラーのためログ出力

                return Visibility.Collapsed;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

呼出し方

View

<UserControl
    x:Class="Hoge.Views.SampleView"
    xmlns:converter="Hoge.Converters">
    <UserControl.Resources>
        <ResourceDictionary>
            <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Button
            Content="サンプルボタン"
            Visibility="{Binding IsButtonVisible, Converter={StaticResource BoolToVisibilityConverter}}" />
    </Grid>
</UserControl>

ViewModel

ViewModelの以下のプロパティがConverterを通して、viewに適用されます。

     public bool IsButtonVisible { get; set; }

2. ViewModelのbool値をViewのstringに変換する

ViewModelのとあるプロパティのbool値がtrueのときはふがふがfalseのときはほげほげという文字列に変換するクラスです。

Converter

namespace Hoge.Converters
{
    public class BoolToTextConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                if (value == null || (bool)value == false)
                {
                    return "ほげほげ";
                }
                else
                {
                    return "ふがふが";
                }
            }
            catch (Exception)
            {
                // エラーのためログ出力

                return "ぴよぴよ";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

呼出し方

View

<UserControl
    x:Class="Hoge.Views.SampleView"
    xmlns:converter="Hoge.Converters">
    <UserControl.Resources>
        <ResourceDictionary>
            <converter:BoolToTextConverter x:Key="BoolToTextConverter" />
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Button
            Content="{Binding isHogeFugaPiyo, Converter={StaticResource BoolToTextConverter}}"
            Visibility="Visible" />
    </Grid>
</UserControl>

ViewModel

     public bool isHogeFugaPiyo { get; set; }

3. ConverterParameterの使用例

xaml側でConverterParameterを使用して、Converterクラスのメソッドにパラメータを設定することもできます。下の例では、Convertクラスの引数parameterinverseの文字があると、VisibilityCollapsedが逆となるよう実装しています。

Converter

namespace Hoge.Converters
{
    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                bool result;
                if (value == null || (bool)value == false)
                {
                    result = false;
                }
                else
                {
                    result = true;
                }

                if (parameter?.ToString().ToLower() == "inverse")
                {
                    return result ? Visibility.Collapsed : Visibility.Visible;
                }
                else
                {
                    return result ? Visibility.Visible: Visibility.Collapsed;
                }

            }
            catch (Exception)
            {
                // エラーのためログ出力

                return Visibility.Collapsed;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

呼出し方

View

VisibilityConverterParameter=inverseを記載しています。

<UserControl
    x:Class="Hoge.Views.SampleView"
    xmlns:converter="Hoge.Converters">
    <UserControl.Resources>
        <ResourceDictionary>
            <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <Button
            Content="サンプルボタン"
            Visibility="{Binding IsButtonVisible, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=inverse}" />
    </Grid>
</UserControl>

xamlでこのようにConverterParameterを指定すると、ConvertBackメソッドの引数parameterにも同じようにConverterParameterで指定した文字 (ここではinverse) が入ってきます。

ViewModel

     public bool IsButtonVisible { get; set; }

4. ConvertBackの使用例

このサンプルではConvertBackも実装しています。
ConvertメソッドでViewModelのEmum値をstringに変換して、ConvertBackメソッドでViewのstringをViewModelのEnum値に変換しています。
ViewModelのSampleプロパティの値をConvertメソッドを使用してViewの表示値に変換するのは今までのサンプルと同じ動きです。
今回はそれに加えて、ViewのTextBoxに値が入力されLostFocusされた際に、ConvertBackメソッドを通して、ViewModelのSampleプロパティに適切な値が入ります。

namespace Hoge.Converters
{
public class SampleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return "";

            var sample = (SampleEnum)Enum.Parse(typeof(SampleEnum), value.ToString());

            switch (sample)
            {
                case SampleEnum.Hoge:
                    return "ほげ";
                case SampleEnum.Fuga:
                    return "ふが";
                case SampleEnum.Piyo:
                    return "ぴよ";
                default:
                    // エラー処理

                    return "";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string sampleText = (string)value;

            switch (sampleText)
            {
                case "ほげ":
                    return SampleEnum.Hoge;
                case "ふが":
                    return SampleEnum.Fuga;
                case "ぴよ":
                    return SampleEnum.Piyo;
                default:
                    // エラー処理

                    return null;
            }
        }
    }
}

呼出し方

View

<UserControl
    x:Class="Hoge.Views.SampleView"
    xmlns:converter="Hoge.Converters">
    <UserControl.Resources>
        <ResourceDictionary>
            <converter:SampleConverter x:Key="SampleConverter" />
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <TextBox Width="100" Text="{Binding Sample, Converter={StaticResource SampleConverter}" />
    </Grid>
</UserControl>

ViewのTextBoxのLostFocus時にConvertBackメソッドが走るのは、
TextBoxのUpdateSourceTriggerのデフォルト値がUpdateSourceTrigger=LostFocusだからです。
例えばここで以下のようにUpdateSourceTrigger=PropertyChangedを指定すると、テキストボックスに文字が入力されたり、一文字消去されるたびに、ViewModelのプロパティも変更されるので、そのたびにConvertBackメソッドも走ります。

<TextBox Width="100" Text="{Binding Sample, Converter={StaticResource SampleConverter}, UpdateSourceTrigger=PropertyChanged}" />

ViewModel

public Class SampleClass
{
      public enum SampleEnum
      {
          Hoge,
          Fuga,
          Piyo
      }
        
      public SampleEnum Sample { get; set; }
}

おわりに

Converterクラスは使い方によっては色々とバインディングの幅が広がりそうと感じました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?