web-dev-qa-db-ja.com

複数のパラメーターを持つコンバーター

Windows Phone 7アプリケーションで、複数のパラメーターを持つコンバーターをどのように使用しますか?

31
Harshad Bhola

コンバーターは常に IValueConverter を実装します。つまり、 Convert または ConvertBack を呼び出すと、1つの追加パラメーターが渡されます。そのパラメーターはXAMLから抽出されます。

Hitesh Patelが示唆しているように、後で分離するための区切り文字がある限り、パラメーターに複数の値を入力するのを止めることはできませんが、区切り文字としてコンマを使用することはできません。 XAML!

例えば.

XAML

<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
                        Converter={StaticResource MyConverter}, 
                        ConverterParameter=Param1|Param2}" />

コンバータ

public object Convert(object value, Type targetType, object parameter,
    System.Globalization.CultureInfo culture)
{
    string parameterString = parameter as string;
    if (!string.IsNullOrEmpty(parameterString))
    {
        string[] parameters = parameterString.Split(new char[]{'|'});
        // Now do something with the parameters
    }
}

注、パイプ "|"かどうかを確認していません文字はXAMLで有効です(あるはずです)が、そうでない場合は、衝突しない別の文字を選択してください。

それ以降のバージョンの.Netは、最も単純なバージョンのSplitの文字配列を必要としないため、代わりにこれを使用できます。

string[] parameters = parameterString.Split('|');

補遺:

EBayが何年も前にURLで使用していたトリックは、QQでURLのデータを区切ることでした。ダブルQは、テキストデータでは自然には発生しません。エンコードの問題を回避するテキスト区切り文字が表示されなくなった場合は、QQを使用してください...これは分割では機能しません(単一文字が必要ですが、知っておくと便利です):)

51
Gone Coding

DependecyObjectクラスからいつでも派生させて、必要な数のDependencyPropertiesを追加できます。例えば:

ExampleConverter.cs

public class ExampleConverter : DependencyObject, IValueConverter
{
    public string Example
    {
        get => GetValue(ExampleProperty).ToString();
        set => SetValue(ExampleProperty, value);
    }
    public static readonly DependencyProperty ExampleProperty =
        DependencyProperty.Register("Example", typeof(string), typeof(ExampleConverter), new PropertyMetadata(null));

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Do the convert
    }

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

そしてXAMLで:

ExampleView.xaml

<ResourceDictionary>
    <converters:ExampleConverter x:Key="ExampleConverter" Example="{Binding YourSecondParam}"/>
</ResourceDictionary>
...
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
                    Converter={StaticResource ExampleConverter}, 
                    ConverterParameter={Binding YourFirstParam}}" />
11

上記の答えは実現可能かもしれませんが、それらは過度に複雑であるようです。 XAMLコードでIMultiValueConverterを適切なMultiBindingとともに使用するだけです。 ViewModelにFirstValueSecondValue、およびThirdValueのプロパティがあると仮定します。これらはintdouble、およびstring、それぞれ、有効なマルチコンバーターは次のようになります。

C#

public class MyMultiValueConverter : IMultiValueConverter {
  public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
    int firstValue = (int)values[0];
    double secondValue = (double)values[1];
    string thirdValue = (string)values[2];

    return "You said " + thirdValue + ", but it's rather " + firstValue * secondValue;
  }

  public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
    throw new NotImplementedException("Going back to what you had isn't supported.");
  }
}

XAML

<TextBlock.Text>
  <MultiBinding Converter="{StaticResource myNs:MyMultiValueConverter}">
    <Binding Path="FirstValue" />
    <Binding Path="SecondValue" />
    <Binding Path="ThirdValue" />
  </MultiBinding>
</TextBlock.Text>

ProvideValueに必要なMarkupExtensionメソッドをいじる必要も、DependencyObjectinside(!)コンバーターを指定する必要もないので、これが最もエレガントなソリューションであると信じています。

9
Informagic

これは、System.Windows.Markup.MarkupExtensiondocs )を使用して行うことができます。

これにより、引数または戻り値として使用できる値をコンバーターに渡すことができます。次に例を示します。

public class CustomNullToVisibilityConverter : MarkupExtension, IValueConverter
{
    public object NullValue { get; set; }
    public object NotNullValue { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null) return NullValue;

        return NotNullValue;
    }

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

使用法:

...
Visibility="{Binding Property, Converter={cnv:CustomNullToVisibilityConverter NotNullValue=Visible, NullValue=Collapsed}}" />
...

必ず.xamlでコンバータの名前空間を参照してください。

3
Alfie

入力が文字列で機能せず、複数のパラメーター(バインディングではない)がある場合。あなただけのコレクションを渡すことができます。配列に関するUIエディターの問題を回避するために必要なタイプの1つを定義します。

public class BrushCollection : Collection<Brush>
{
}

次に、コレクションを使用してXAMLを追加します

                <TextBox.Background >
                    <Binding Path="HasInitiativeChanged" Converter="{StaticResource changedToBrushConverter}">
                        <Binding.ConverterParameter>
                            <local:BrushCollection>
                                <SolidColorBrush Color="{DynamicResource ThemeTextBackground}"/>
                                <SolidColorBrush Color="{DynamicResource SecondaryColorBMedium}"/>
                            </local:BrushCollection>
                        </Binding.ConverterParameter>
                    </Binding>

                </TextBox.Background>

次に、結果をコンバーターの適切な型の配列にキャストします。

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

        BrushCollection brushes = (BrushCollection)parameter;
1
Kyle Olson