整数をConverterParameterとして渡す方法は?


95

私は整数プロパティにバインドしようとしています:

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter=0}" />

そして私のコンバーターは:

[ValueConversion(typeof(int), typeof(bool))]
public class IntToBoolConverter : IValueConverter
{
    public object Convert(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
    }
}

問題は、コンバーターが呼び出されたときにパラメーターが文字列であることです。整数である必要があります。もちろん、文字列を解析できますが、そうする必要がありますか?

助けてくれてありがとう


2
バインディングの構文が少し異なるWindows Phoneプラットフォームでこれを実現する方法を知っている人はいますか?{Binding PROPERTY、Converter = {StaticResource MYCONVERTER}、ConverterParameter = INT_VAL}この例では、INT_VALは文字列として渡されます
Krzysztof Kaczor

回答:


106

やった!

<RadioButton Content="None"
             xmlns:sys="clr-namespace:System;assembly=mscorlib">
    <RadioButton.IsChecked>
        <Binding Path="MyProperty"
                 Converter="{StaticResource IntToBoolConverter}">
            <Binding.ConverterParameter>
                <sys:Int32>0</sys:Int32>
            </Binding.ConverterParameter>
        </Binding>
    </RadioButton.IsChecked>
</RadioButton>

秘訣は、基本的なシステムタイプの名前空間を含め、要素の形式で少なくともConverterParameterバインディングを記述することです。


2
これによって、「パラメータ」パラメータIValueConverter.Convert()のタイプがであるという事実は変わりません。それでもキャスト/解析する必要があります...object
Dan J

6
@djacobson-Trueですが、ValueConversion属性で指定できます。これが実際にコンパイル時に使用されるのか、実行時に使用されるのかは正確にはわかりません。元のポスターの質問に関して、彼は「整数である必要があります。もちろん文字列を解析できますが、そうする必要がありますか?」と指定しました。だから私の答えは、文字列の解析はなく、整数のボックス化解除だけであるという点で軽減します。
jpierson 2011

51

完全を期すために、もう1つの可能な解決策(おそらく入力を減らすこと):

<Window
    xmlns:sys="clr-namespace:System;assembly=mscorlib" ...>
    <Window.Resources>
        <sys:Int32 x:Key="IntZero">0</sys:Int32>
    </Window.Resources>

    <RadioButton Content="None"
                 IsChecked="{Binding MyProperty,
                                     Converter={StaticResource IntToBoolConverter},
                                     ConverterParameter={StaticResource IntZero}}" />

(もちろん、Windowに置き換えることができUserControl、そしてIntZero近い実際の使用の場所に定義されてもよいです。)


44

WPF人々がを使用することに嫌悪する傾向がある理由がわかりませんMarkupExtension。これは、ここで言及した問題を含む多くの問題の完璧な解決策です。

public sealed class Int32Extension : MarkupExtension
{
    public Int32Extension(int value) { this.Value = value; }
    public int Value { get; set; }
    public override Object ProvideValue(IServiceProvider sp) { return Value; }
};

このマークアップ拡張がXAML名前空間「m」で使用できる場合、元の投稿者の例は次のようになります。

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter={m:Int32 0}}" />

これが機能するのは、バインディングのConverterParameter引数が(情報量が少ない)オブジェクト型であるのに対し、マークアップ拡張パーサーはコンストラクタ引数の強い型を確認して変換できるためです。


ありがとう、それは役に立ちました。これが私の最初のXAML拡張機能になります。しかしValueobjectintボックス化するのを避けるために、ではなくを作成する方が良いと思いますProvideValue。(そして、private直接に違法なものを割り当てないようにします)。
Zeus

1
@Zeusは通常ProvideValue、マークアップ拡張機能インスタンスごとに1回だけ呼び出されるため、ボクシングはいずれにしても1回だけ実行する必要があります。コンストラクターでこれを行わないことで、ProvideValue呼び出されない場合は完全にボックス化を回避します。作るためとしてValue、民間、これはでマークアップ拡張機能使用不可能にXAMLオブジェクト要素構文:msdn.microsoft.com/en-us/library/...を
グレンSlayden

あなたの最後の段落は間違っています。これは型変換と呼ばれ、プロパティにも適用されます。実は、それBinding.ConverterParameterは特定の型を持たない(それは単なるobject)ので、パーサーはどの変換を適用すべきかを知らないので、すべてのリテラルは単に文字列として扱われます。
HB

(つまり、拡張機能にデフォルトのコンストラクターがある場合は、{m:Int32 Value=0}同様に機能します。)
HB

5

使用しないでくださいvalue.Equals。使用する:

  Convert.ToInt32(value) == Convert.ToInt32(parameter)

8
どうして使いたくないのvalue.Equals
ザック

1

XAMLでConverterValueの型情報を何らかの形で表現するのは良いことですが、現時点では可能ではないと思います。ですから、コンバーターオブジェクトをいくつかのカスタムロジックによって期待される型に解析する必要があると思います。別の方法は見ていません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.