WPF:コンバーターのいくつかのオプション

コンバーターに関する最初の記事では、コンバーターをマークアップ拡張機能として使用する方法について説明しました。 コンバーターのトピックを続けて、コンバーターのパラメーターについてお話したいと思います。



多くの場合、UIで1つのオブジェクトを表すようにバインディングソースを正しく変換するには、オブジェクトの変換方法を示すパラメーターをコンバーターに渡す必要があります。 日付の例に戻って、プログラムで日付をいくつかのカレンダーで表示でき、正しい変換のために、バインディングソースが表すカレンダー日付をコンバーターに通知する必要があると仮定します。これは次のように実行できます。

<Label Content="{Binding Path=Date, Converter={StaticResource dateConverter}, ConverterParameter='Gregorian'}" />
      
      





同様に、MarkupExtensionのようなコンバーターを使用する場合:

 <Label Content="{Binding Path=Date, Converter={converters:DateTimeToString}, ConverterParameter='Gregorian'}" />
      
      





このコンバーターが呼び出されると、値「Gregorian」がその入力パラメーター「parameter」に含まれ、日付がグレゴリオ暦にあることがすでにわかります。

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { DateTime date = (DateTime)value; string calendar = (string)parameter; if (calendar == "Gregorian") return DateTimeHelpers.GregorianToString(calendar); else if (calendar == "Gregorian") return DateTimeHelpers.GregorianToString(calendar); }
      
      





いくつかのパラメーター



これはもちろん素晴らしいことですが、1つではなく2つ以上のパラメーターをコンバーターに転送する必要がある場合はどうでしょうか。 標準的な方法では、これは機能しません。 ただし、urrri habrayuzerで示唆されているように、コンバーターが同時にMarkupExtensionである場合これは簡単に実装できます。 彼の許可を得て、この方法を説明します。



基礎として、 最初の記事のコードを使用します。 まず、基本クラスをわずかに変更します。

  public abstract class ConvertorBase<T> : MarkupExtension, IValueConverter where T : class, new() { /// <summary> /// Must be implemented in inheritor. /// </summary> public abstract object Convert(object value, Type targetType, object parameter, CultureInfo culture); /// <summary> /// Override if needed. /// </summary> public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } public override object ProvideValue(IServiceProvider serviceProvider) { return this; } }
      
      





変更後、クラスの静的インスタンスではなく、現在のインスタンスを返します。

コンバーターには、日付と出力の形式の2つのパラメーターが必要だとしましょう。 コンバーターを変更します。

  public class DateTimeToString : ConvertorBase<DateTimeToString> { /// Format for converting DateTime to string. /// </summary> public string Format { set; private get; } /// <summary> /// Date of what calendar current instance is representing. /// </summary> public string Calendar { set; private get; } public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) { DateTime date = (DateTime)value; if (calendar == "Gregorian") return DateTimeHelpers.GregorianToString(date, Format); else if (calendar == "Gregorian") return DateTimeHelpers.GregorianToString(date, Format); } }
      
      





コンバーターの使用例:

 <Label Content="{Binding Path=Date, Converter={converters:DateTimeToString Calendar='Gregorian', Format ='Today is {0}'}}" />
      
      





コンバーターが追加された後にプロジェクトが再構築されると、エディターはプロパティオプションを提供します。



パラメーターの一部がオプションである場合は、省略できることに注意してください。

 <Label Content="{Binding Path=Date, Converter={converters:DateTimeToString}" />
      
      





コンバーターが呼び出されると、対応するパラメーターは空になります。 当然、そのような状況は予見されなければなりません。 フォーマットが必要で、カレンダーが追加のパラメーターであるとします。デフォルトでは、カレンダーはグレゴリオ暦であると想定します。 入力パラメーターのチェックをコンバーターに追加しましょう。

  [ValueConversion(typeof(DateTime), typeof(String))] public class DateTimeToString : ConvertorBase<DateTimeToString> { /// <summary> /// Format string. /// </summary> public string Format { set; private get; } /// <summary> /// Date of what calendar current instance is representing. /// </summary> public string Calendar { set { _calendar = value; } private get { return _calendar; } } /// <summary> /// Default calendar. /// </summary> private string _calendar = "Gregorian"; public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) { DateTime date = (DateTime)value; Debug.Assert(date != null, "Date is missing."); Debug.Assert(Format != null, "Format is missing."); if (Calendar == "Gregorian") return DateTimeHelpers.GregorianToString(date, Format); else if (Calendar == "Gregorian") return DateTimeHelpers.GregorianToString(date, Format); } }
      
      





日付がコンバーターに転送されない場合、または形式が指定されていない場合、デバッグに非常に役立つような素晴らしいウィンドウが表示されます。



また、ValueConversion属性をクラスに追加しました(typeof(DateTime)、typeof(String))。 このコンバーターがDateTimeを文字列に変換することを示します。 すべてのコンバーターにこのような属性を指定することをお勧めします。クラスヘッダーを見ると、変換先と変換先がすぐにわかるからです。



その結果、任意の数のパラメーターをコンバーターに転送する方法を学びました。これらのパラメーターには名前が付けられます。 この方法の唯一の欠点は、コンバーターが使用される各要素に対して、コンバーターの独自のインスタンスが作成されることです。 したがって、おそらく、このメソッドは、多数の要素を持つコレクションではうまく機能しません。



All Articles