Defina o valor como nulo na ligação WPF


116

por favor, dê uma olhada na seguinte linha

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

Esta propriedade Price de cima é um Decimal?(decimal anulável).

Eu quero que se o usuário excluir o conteúdo da caixa de texto (ou seja, inserir uma string vazia, ele deve atualizar automaticamente a fonte com nulo (Nada em VB).

Alguma ideia de como posso fazer 'Xamly'?

Respostas:


226

Estou usando o .NET 3.5 SP1, então é muito simples:

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

Que significa (obrigado Gregor pelo seu comentário):

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

sysé o namespace xml importado para Systemem mscorlib:

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

Espero que tenha ajudado.


13
Na verdade, TargetNullValue funciona muito bem. O que ele faz é definir uma equivalência entre o valor fornecido e nulo. Portanto, neste caso, quando o valor vinculado for nulo, ele exibirá uma string vazia e quando o valor do destino for a string vazia, ele definirá o valor vinculado como nulo.
— Bryan Anderson

4
O TargetNullValue funciona. Obtive os mesmos resultados ao usar o conversor de valor. Você também pode simplificar a expressão: <TextBox Text = "{Binding Price, TargetNullValue = ''}" />
— Gregor Slavec

2
Estou confuso - o OP diz: "..ele deveria atualizar automaticamente a fonte com nulo [quando o destino é uma string vazia].", Mas o TargetNullValue atualiza o destino , não a fonte !
— markmnl

1
Você não é o único confuso - há comentários confusos na outra resposta também. O OP também fica um pouco confuso, quando diz atualizar o código-fonte, ele realmente quer dizer o destino no WPF speak (o código-fonte é a propriedade Text no TextBox). TargetNullValue diz qual valor definir como Source quando o Target for null. O reverso disso, que é o que estamos aproveitando aqui, é que quando a fonte for atualizada para este valor especificado, o destino será definido como nulo.
— Nathan Phillips

@markmnl Embora TargetNullValue tenha de fato a intenção de atualizar o Targete não o Source, esta solução ainda funciona por algum motivo (não consegui descobrir o porquê).
— Tim Pohlmann,

12

Este conversor de valor deve fazer o truque:

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 uma instância deste conversor nos recursos:

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

E use-o em sua ligação:

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

Observe que TargetNullValuenão é apropriado aqui: ele é usado para definir qual valor deve ser usado quando o sourceda vinculação é nulo. Aqui Pricenão é a fonte, é uma propriedade da fonte ...


2
Um conversor é a maneira adequada de fazer isso e você não pode definir esses conversores em XAML. Os conversores permitem que você altere o comportamento de conversão padrão "objeto para objeto" na vinculação de dados, que é o que você deseja fazer.
— Will Eddins

O problema no meu caso é que eu já uso um conversor aqui que faz outra coisa. Eu postei uma resposta, por favor, dê uma olhada.
— Shimmy Weitzhandler

pode querer usar IsNullOrWhiteSpace () para permitir que "" seja contado como nulo (provavelmente o que você deseja)
— Simon_Weaver

+1 No entanto: o preço é sua fonte aqui, mas você está correto. TargetNullValue não é apropriado aqui - TargetNullValue define o destino quando a fonte é nula - enquanto queremos definir a fonte (como nulo) quando o destino é um determinado valor (um vazio string) - que o seu conversor faz.
— markmnl

5

Você pode tentar usar um ValueConverter (IValueConverter) http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx

Da parte de trás da minha cabeça aqui, 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);
    }
}

(Pode ser necessário alguns ajustes)


Eu preferiria uma forma Xamly, mas não consigo pensar em nada
— Shimmy Weitzhandler
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.