Imposta il valore su null nell'associazione WPF


116

si prega di dare un'occhiata alla riga seguente

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

Questa proprietà Price dall'alto è un Decimal?(decimale nullable).

Voglio che se l'utente cancella il contenuto della casella di testo (cioè inserisce una stringa vuota, dovrebbe aggiornare automaticamente l'origine con null (Nothing in VB).

Qualche idea su come posso farlo "Xamly"?

Risposte:


226

Sto usando .NET 3.5 SP1 quindi è molto semplice:

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

Che sta per (grazie Gregor per il tuo commento):

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

sysè lo spazio dei nomi xml importato per Systemin mscorlib:

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

Spero che abbia aiutato.


13
In realtà TargetNullValue funziona perfettamente. Quello che fa è impostare un'equivalenza tra il valore dato e null. Quindi, in questo caso, quando il valore associato è null, verrà visualizzata una stringa vuota e quando il valore del target è una stringa vuota, il valore associato verrà impostato su null.
Bryan Anderson

4
TargetNullValue funziona. Ho ottenuto gli stessi risultati utilizzando il convertitore di valore. Puoi anche semplificare l'espressione: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec

2
Sono confuso - l'OP dice: "..dovrebbe aggiornare automaticamente la sorgente con null [quando Target è una stringa vuota].", Ma TargetNullValue aggiorna la destinazione , non la sorgente !
markmnl

1
Non sei l'unico confuso - ci sono commenti confusi anche sull'altra risposta. Anche l'OP è leggermente confuso, quando dice di aggiornare la fonte, in realtà significa che il Target in WPF parla (la fonte è la proprietà Text sul TextBox). TargetNullValue indica il valore su cui impostare Source quando Target è null. Il contrario di ciò, che è ciò di cui stiamo approfittando qui, è che quando l'origine viene aggiornata a questo valore specificato, la destinazione verrà impostata su null.
Nathan Phillips

@markmnl Sebbene TargetNullValue sia inteso effettivamente per aggiornare Targete non per Source, questa soluzione fa ancora il trucco per qualche motivo (non sono riuscito a capire perché).
Tim Pohlmann

12

Questo convertitore di valori dovrebbe fare il trucco:

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

Dichiara un'istanza di questo convertitore nelle risorse:

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

E usalo nella tua rilegatura:

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

Nota che TargetNullValuenon è appropriato qui: viene utilizzato per definire quale valore deve essere utilizzato quando il valore sourcedell'associazione è nullo. Qui Pricenon è la fonte, è una proprietà della fonte ...


2
Un convertitore è il modo corretto per eseguire questa operazione e non puoi definire questi convertitori in XAML. I convertitori ti consentono di modificare il comportamento di conversione predefinito "da oggetto a oggetto" nell'associazione dati, che è ciò che desideri fare.
Will Eddins

Il problema nel mio caso è che uso già un convertitore che fa un'altra cosa. Ho pubblicato una risposta, per favore dai un'occhiata.
Shimmy Weitzhandler

potresti voler usare IsNullOrWhiteSpace () per consentire a "" di essere conteggiato come nullo (molto probabilmente quello che vuoi)
Simon_Weaver

+1 Tuttavia: il prezzo è la tua fonte qui ma hai ragione TargetNullValue non è appropriato qui - TargetNullValue imposta il target quando l'origine è nulla - mentre noi vogliamo impostare l' origine (su null) quando l'obiettivo è un certo valore (un vuoto string) - cosa che fa il tuo convertitore.
markmnl

5

Puoi provare a utilizzare ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Della parte posteriore della mia testa qui, qualcosa come:

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

(Potrebbe essere necessario qualche ritocco però)


Preferirei un modo Xamly, ma non riesco a pensare a niente
Shimmy Weitzhandler
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.