Setel nilai ke nol dalam pengikatan WPF

116

silakan lihat baris berikut

<TextBox Text="{Binding Price}"/>

Properti Price dari atas ini adalah Decimal?(Desimal Nullable).

Saya ingin jika pengguna menghapus konten kotak teks (yaitu memasukkan string kosong, itu harus memperbarui sumber secara otomatis dengan null (Tidak ada di VB).

Adakah ide tentang bagaimana saya bisa melakukannya 'Xamly'?

Shimmy Weitzhandler
sumber

Jawaban:

226

Saya menggunakan .NET 3.5 SP1 jadi ini sangat sederhana:

<TextBox Text="{Binding Price, TargetNullValue=''}"/>

Yang merupakan singkatan (terima kasih Gregor atas komentar Anda):

<TextBox Text="{Binding Price, TargetNullValue={x:Static sys:String.Empty}}"/>

sysadalah namespace xml yang diimpor untuk Systemdi mscorlib:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

Semoga membantu.

Shimmy Weitzhandler
sumber
13
Sebenarnya TargetNullValue berfungsi dengan baik. Apa yang dilakukannya adalah mengatur kesetaraan antara nilai yang diberikan dan nol. Jadi dalam kasus ini ketika nilai terikat adalah null itu akan menampilkan string kosong dan ketika nilai target adalah string kosong itu akan mengatur nilai terikat menjadi null.
Bryan Anderson
4
TargetNullValue berfungsi. Saya mendapat hasil yang sama saat menggunakan konverter nilai. Anda juga dapat menyederhanakan ekspresi: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec
2
Saya bingung - OP mengatakan: "..itu harus memperbarui sumber secara otomatis dengan null [ketika Target adalah string kosong].", Tetapi TargetNullValue memperbarui Target , bukan Source !
markmnl
1
Anda bukan satu-satunya yang bingung - ada juga komentar yang membingungkan di jawaban lain. OP juga agak bingung, ketika dia mengatakan perbarui sumber, yang dia maksud sebenarnya adalah Target di WPF yang berbicara (sumbernya adalah properti Teks di TextBox). TargetNullValue mengatakan nilai apa yang harus disetel Sumber ketika Target adalah null. Kebalikan dari ini, yang kita manfaatkan di sini, adalah ketika sumber diperbarui ke nilai yang ditentukan ini, maka target akan disetel ke nol.
Nathan Phillips
@markmnl Sementara TargetNullValue memang dimaksudkan untuk memperbarui Targetdan bukan Source, solusi ini masih melakukan trik untuk beberapa alasan (saya tidak tahu mengapa).
Tim Pohlmann
12

Pengonversi nilai ini harus melakukan trik:

public class StringToNullableDecimalConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
        CultureInfo culture)
    {
        decimal? d = (decimal?)value;
        if (d.HasValue)
            return d.Value.ToString(culture);
        else
            return String.Empty;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        string s = (string)value;
        if (String.IsNullOrEmpty(s))
            return null;
        else
            return (decimal?)decimal.Parse(s, culture);
    }
}

Deklarasikan sebuah instance dari konverter ini di sumber sumber:

<Window.Resources>
    <local:StringToNullableDecimalConverter x:Key="nullDecimalConv"/>
</Window.Resources>

Dan gunakan dalam penjilidan Anda:

<TextBox Text="{Binding Price, Converter={StaticResource nullDecimalConv}}"/>

Catatan yang TargetNullValuetidak tepat di sini: ini digunakan untuk menentukan nilai mana yang harus digunakan ketika sourcepengikatan adalah null. Ini Pricebukan sumbernya, ini adalah properti dari sumber ...

Thomas Levesque
sumber
2
Konverter adalah cara yang tepat untuk melakukan ini, dan Anda tidak dapat menentukan konverter ini di XAML. Pengonversi memungkinkan Anda untuk mengubah perilaku konversi default "objek ke objek" dalam pengikatan data, yang ingin Anda lakukan.
Will Eddins
Masalah dalam kasus saya adalah saya sudah menggunakan konverter di sini yang melakukan hal lain. Saya memposting jawaban, silakan lihat.
Shimmy Weitzhandler
mungkin ingin menggunakan IsNullOrWhiteSpace () untuk mengizinkan "" dihitung sebagai null (kemungkinan besar sesuai keinginan Anda)
Simon_Weaver
+1 Namun: Harga adalah sumber Anda di sini, tetapi Anda benar TargetNullValue tidak sesuai di sini - TargetNullValue menyetel target saat sumbernya null - sedangkan kami ingin menyetel sumber (ke null) saat targetnya adalah nilai tertentu (kosong string) - yang dilakukan konverter Anda.
markmnl
5

Anda dapat mencoba menggunakan ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Dari belakang kepalaku di sini, sesuatu seperti:

public class DoubleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
        return (double)value;
    }

    public object ConvertBack(object value, Type targetType, 
        object parameter, CultureInfo culture)
    {
    var doubleValue = Convert.ToDouble(value);

    return (doubleValue == 0 ? null : doubleValue);
    }
}

(Mungkin perlu beberapa penyesuaian)

TimothyP
sumber
Saya lebih suka cara Xamly, tetapi saya tidak dapat memikirkan apa pun
Shimmy Weitzhandler