wpf - Use un valor predeterminado cuando el enlace no se puede evaluar debido a un valor nulo
silverlight data-binding (3)
Hey TargetNullValue y FallbackValue funciona. Puede ser que la versión de .NET que está utilizando sea incorrecta.
Requiere .NET Framework 3.5 SP1 .TargetNullValue y FallbackValue es una nueva adición a la clase Binding
¿Hay alguna manera de asignar un valor especial cuando un enlace no se puede evaluar debido a un valor nulo en la ruta de acceso de la propiedad ?
Por ejemplo, si tengo una propiedad Nombre en una clase Cliente y un enlace como este:
{Binding CurrentCustomer.Name}
Cuando CurrentCustomer es nulo, me gustaría que el enlace produzca la cadena "---".
"TargetNullValue" y "FallbackValue" no parecen hacer el truco.
Gracias de antemano por tu ayuda.
EDITAR :
De hecho, lo que estoy tratando de hacer es sustituir un valor fuente nuevo en lugar del verdadero cuando no está disponible. El escenario real es el siguiente:
Se usa un valor de bool para determinar la visibilidad de un control, pero cuando este valor no es alcanzable, me gustaría reemplazarlo por "falso".
Aquí hay una ilustración que imita perfectamente mi caso de uso real:
MainPage.xaml.cs:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace TestSilverlightBindingDefaultValue
{
public class BoolToVisibilityConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (bool)value ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
public class Customer
{
public bool HasACar
{
get;
set;
}
}
public partial class MainPage : UserControl
{
public static readonly DependencyProperty CurrentCustomerProperty =
DependencyProperty.Register("CurrentCustomer", typeof(Customer), typeof(MainPage), null);
public Customer CurrentCustomer
{
get { return this.GetValue(CurrentCustomerProperty) as Customer; }
set { this.SetValue(CurrentCustomerProperty, value); }
}
public MainPage()
{
InitializeComponent();
this.CurrentCustomer = null;
this.DataContext = this;
}
}
}
MainPage.xaml:
<UserControl x:Class="TestSilverlightBindingDefaultValue.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:TestSilverlightBindingDefaultValue"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<local:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
</UserControl.Resources>
<StackPanel x:Name="LayoutRoot" Background="White">
<TextBlock Text="You have a car" Visibility="{Binding CurrentCustomer.HasACar,Converter={StaticResource boolToVisibilityConverter}}" />
</StackPanel>
FallbackValue no es la solución porque solo cambiaría el valor generado y no el valor de origen.
Abe Heidebrecht ha proporcionado la solución perfecta para WPF con PriorityBinding, pero no existe en Silverlight .
EDICIÓN FINAL : La segunda solución de Abe Heidebrecht , es decir, envolviendo en otro elemento, está funcionando perfectamente.
Puede usar un enlace de prioridad :
<TextBlock>
<TextBlock.Text>
<PriorityBinding>
<Binding Path="CurrentCustomer.Name" />
<Binding Source="---" />
</PriorityBinding>
</TextBlock.Text>
</TextBlock>
De acuerdo, para Silverlight es probablemente más fácil envolver el elemento en un contenedor (como un borde). Luego tiene un IValueConverter
para convertir null a Visibility.Collapsed
, y cualquier otra cosa a Visibility.Visible
:
public class NullToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Y úsalo así:
<Border Visibility="{Binding CurrentCustomer, Converter={StaticResource NullToVisibilityConverter}}">
<TextBlock Text="You have a car" Visibility="{Binding CurrentCustomer.HasACar,Converter={StaticResource boolToVisibilityConverter}}" />
</Border>
si usa .NET framework 3.5 o superior, puede usar targetnullValue. En este ejemplo, si ha creado la propiedad de dependencia denominada BackgroundProperty, puede usar targetNullvalue en la declaración de enlace. En este caso, paso el color de ResourcesDictionary.
<Style x:Key="LabelAxisNameStyle" TargetType="{x:Type Label}">
<Setter Property="Background">
<Setter.Value>
<Binding Path="BackgroundProperty" TargetNullValue="{StaticResource LabelTitleBrush}"/>
</Setter.Value>
</Setter>
</Style>