ConverterParameter olarak bir tamsayı nasıl iletilir?


95

Bir tamsayı özelliğine bağlanmaya çalışıyorum:

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

ve dönüştürücüm:

[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;
    }
}

sorun, dönüştürücüm çağrıldığında parametrenin string olmasıdır. tam sayı olmasına ihtiyacım var. tabii ki dizeyi ayrıştırabilirim, ama mecbur muyum?

herhangi bir yardım için teşekkürler konstantin


2
Bağlamalar için biraz farklı sözdizimimiz olan Windows Phone platformunda bunu nasıl başaracağını bilen var mı? Bu örnekte {Binding PROPERTY, Converter = {StaticResource MYCONVERTER}, ConverterParameter = INT_VAL} bir dize olarak geçirilecek
Krzysztof Kaczor

Yanıtlar:


107

Buyurun!

<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>

İşin püf noktası, temel sistem türleri için ad alanını dahil etmek ve daha sonra en azından ConverterParameter bağlamasını öğe biçiminde yazmaktır.


2
Bu, IValueConverter.Convert()"s " parametresi " parametresinin türünün olduğu gerçeğini değiştirmez object. Yine de döküm / ayrıştırmanız gerekiyor ...
Dan J

6
@djacobson - Doğru, ancak ValueConversion özniteliğinin belirtmenize izin verdiği şey budur. Bunun gerçekten derleme zamanında mı yoksa çalışma zamanında mı kullanıldığından tam olarak emin değilim. Orijinal posterler sorusuyla ilgili olarak, "onun bir tamsayı olmasına ihtiyacım var. Tabii ki dizeyi ayrıştırabilirim, ama yapmalı mıyım?" Bu yüzden cevabım, bir dizgenin ayrıştırılması olmadığı, sadece hala çok daha güvenli olduğum bir tamsayının kutudan çıkarılması olduğunu hafifletiyor.
jpierson

51

Tamlık için, olası bir çözüm daha (belki daha az yazarak):

<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}}" />

(Tabii ki Windowile değiştirilebilir UserControlve IntZerogerçek kullanım yerine daha yakın tanımlanabilir.)


45

WPFİnsanların neden kullanmaya karşı isteksiz olduklarından emin değilim MarkupExtension. Burada bahsedilen sorun dahil birçok sorun için mükemmel bir çözümdür.

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; }
};

Bu biçimlendirme uzantısı XAML'm' ad alanında mevcutsa , orijinal göndericinin örneği şöyle olur:

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

Bu işe yarar, çünkü biçimlendirme uzantısı ayrıştırıcısı yapıcı bağımsız değişkeninin güçlü türünü görebilir ve buna göre dönüştürebilir, oysa Binding'in ConverterParameter bağımsız değişkeni (daha az bilgilendirici) Nesne tiplidir.


Teşekkürler, bu faydalı oldu. İlk XAML uzantım olacak. Ama bence her seferinde kutudan kaçınmak yerine Valuebir yapmak objectdaha iyidir . (Ve sonra, yasadışı bir şeyi doğrudan atamaktan kaçın). intProvideValueprivate
Zeus

1
@Zeus Tipik ProvideValueolarak işaretleme uzantısı örneği başına yalnızca bir kez çağrılır, bu nedenle kutulama yine de yalnızca bir kez yapılmalıdır. Yapıcıda yapmayarak ProvideValue, asla çağrılmazsa, boks yapmaktan tamamen kaçınıyorum . ValueÖzel hale getirmeye gelince , bu, XAMLnesne öğesi sözdiziminde işaretleme uzantısının kullanılmasını
engeller

Son paragrafınız yanlış. Tip dönüşümü olarak adlandırılır ve aynı zamanda özellikler için de geçerlidir. Mesele şu ki Binding.ConverterParameter, bunun belirli bir türü yoktur (bu sadece bir object), bu nedenle ayrıştırıcı hangi dönüşümü uygulayacağını bilmez, bu nedenle her değişmez değer yalnızca bir dizge olarak değerlendirilir.
HB

(Yani, uzantınız varsayılan bir kurucunuz varsa, o zaman da {m:Int32 Value=0}aynı şekilde çalışacaktır.)
HB

4

Kullanmayın value.Equals. Kullanım:

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

8
Neden kullanmak istemiyorum value.Equals?
Zack

0

XAML'de ConverterValue için tür bilgisini bir şekilde ifade etmek güzel olurdu, ancak şimdilik bunun mümkün olduğunu sanmıyorum. Bu yüzden, Dönüştürücü Nesnesini bazı özel mantıkla beklenen türe göre ayrıştırmanız gerektiğini tahmin ediyorum. Başka bir yol görmüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.