web-dev-qa-db-fra.com

Liaison WPF - Valeur par défaut pour la chaîne vide

Existe-t-il un moyen standard de définir une valeur par défaut ou une valeur de secours pour une liaison WPF si la chaîne liée est vide?

<TextBlock Text="{Binding Name, FallbackValue='Unnamed'" />

FallbackValue ne semble entrer en jeu que lorsque Name est null, mais pas lorsqu'il est défini sur String.Empty.

31
kroimon

J'avais l'impression que FallbackValue fournit une valeur lorsque la liaison échoue et TargetNullValue fournit une valeur lorsque la valeur liée est null.

Pour faire ce que vous voulez, vous aurez besoin d'un convertisseur (éventuellement avec un paramètre) pour convertir une chaîne vide en valeur cible ou de placer la logique dans votre modèle de vue.

Je voudrais probablement aller avec un convertisseur quelque chose comme ça (non testé).

public class EmptyStringConverter : MarkupExtension, IValueConverter
{  
    public object Convert(object value, Type targetType, 
                          object parameter, CultureInfo culture)
    {
        return string.IsNullOrEmpty(value as string) ? parameter : value;
    }

    public object ConvertBack(object value, Type targetType, 
                              object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}
30
Phil

DataTrigger est la façon dont je le fais comme ceci:

<TextBox>
  <TextBox.Style>
        <Style TargetType="{x:Type TextBox}"  BasedOn="{StaticResource ReadOnlyTextBox}">
            <Setter Property="Text" Value="{Binding Name}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Name.Length, FallbackValue=0, TargetNullValue=0}" Value="0">
                    <Setter Property="Text" Value="{x:Static local:ApplicationLabels.NoValueMessage}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
61
iltzortz

Vous devriez créer un convertisseur pour cela, qui implémente IValueConverter

public class StringEmptyConverter : IValueConverter {

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
      return string.IsNullOrEmpty((string)value) ? parameter : value;
    }

public object ConvertBack(
      object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
      throw new NotSupportedException();
    }

}

Ensuite, dans xaml, vous fournissez simplement le convertisseur à la liaison (xxx représente simplement votre Window/UserControl/Style ... où la liaison est)

<xxx.Resources>
<local:StringEmptyConverter x:Key="StringEmptyConverter" />
</xxx.Resources>
<TextBlock Text="{Binding Name, Converter={StaticResource StringEmptyConverter}, ConverterParameter='Placeholder Text'}" />
6
Viv

Vous pouvez utiliser un convertisseur et procéder à la validation correspondante.

Binding="{Binding Path=Name, Converter={StaticResource nameToOtherNameConverter}}"

et dans votre convertisseur

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (!string.IsNullOrEmpty(value.ToString()))
        { /*do something and return your new value*/ }
0
Santux