Establecer valor en nulo en el enlace de WPF

116

por favor, eche un vistazo a la siguiente línea

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

Esta propiedad Price de arriba es un Decimal?(decimal que acepta valores NULL).

Quiero que si el usuario elimina el contenido del cuadro de texto (es decir, ingresa una cadena vacía, debería actualizar automáticamente la fuente con nulo (Nada en VB).

¿Alguna idea sobre cómo puedo hacerlo 'Xamly'?

Shimmy Weitzhandler
fuente

Respuestas:

226

Estoy usando .NET 3.5 SP1, así que es muy simple:

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

Lo que significa (gracias Gregor por tu comentario):

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

syses el espacio de nombres XML importado para Systemen mscorlib:

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

Espero que haya ayudado.

Shimmy Weitzhandler
fuente
13
En realidad, TargetNullValue funciona bien. Lo que hace es establecer una equivalencia entre el valor dado y nulo. Entonces, en este caso, cuando el valor enlazado sea nulo, mostrará una cadena vacía y cuando el valor del objetivo sea la cadena vacía, establecerá el valor enlazado en nulo.
Bryan Anderson
4
TargetNullValue funciona. Obtuve los mismos resultados al usar el convertidor de valores. También puede simplificar la expresión: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
Gregor Slavec
2
Estoy confundido: el OP dice: "... debería actualizar automáticamente la fuente con nulo [cuando el destino es una cadena vacía]", pero TargetNullValue actualiza el destino , no el origen .
markmnl
1
No eres el único confundido, también hay comentarios confusos sobre la otra respuesta. El OP también está un poco confundido, cuando dice actualizar la fuente, en realidad se refiere a Target en WPF speak (la fuente es la propiedad Text en TextBox). TargetNullValue dice qué valor establecer el origen cuando el destino es nulo. Lo contrario de esto, que es lo que estamos aprovechando aquí, es que cuando la fuente se actualiza a este valor especificado, el objetivo se establecerá en nulo.
Nathan Phillips
@markmnl Si bien TargetNullValue está destinado a actualizar el Targety no el Source, esta solución aún funciona por alguna razón (no pude entender por qué).
Tim Pohlmann
12

Este convertidor de valores debería hacer el truco:

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

Declare una instancia de este convertidor en los recursos:

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

Y utilícelo en su encuadernación:

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

Tenga en cuenta que TargetNullValueno es apropiado aquí: se usa para definir qué valor debe usarse cuando el sourcedel enlace es nulo. Aquí Priceno está la fuente, es una propiedad de la fuente ...

Thomas Levesque
fuente
2
Un convertidor es la forma correcta de hacer esto y no puede definir estos convertidores en XAML. Los convertidores le permiten cambiar el comportamiento de conversión predeterminado de "objeto a objeto" en el enlace de datos, que es lo que desea hacer.
Will Eddins
El problema en mi caso es que ya uso aquí un convertidor que hace otra cosa. Publiqué una respuesta, por favor, eche un vistazo.
Shimmy Weitzhandler
es posible que desee usar IsNullOrWhiteSpace () para permitir que "" se cuente como nulo (probablemente lo que desee)
Simon_Weaver
+1 Sin embargo: el precio es su fuente aquí pero está en lo correcto TargetNullValue no es apropiado aquí - TargetNullValue establece el objetivo cuando la fuente es nula, mientras que queremos establecer la fuente (en nulo) cuando el objetivo es un cierto valor (un valor vacío string) - lo que hace su convertidor.
markmnl
5

Puede intentar usar un ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

De la parte de atrás de mi cabeza aquí, algo como:

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

(Aunque podría necesitar algunos ajustes)

TimothyP
fuente
Preferiría una forma Xamly, pero no puedo pensar en nada
Shimmy Weitzhandler