wpf xaml data-binding coalesce targetnullvalue

wpf - Equiv. para unir() en enlace XAML?



data-binding coalesce (3)

Como está vinculando a una String , null es un valor válido para PriorityBinding . No estoy seguro de cuáles son los tipos de propiedad de la clase Item, pero si usa Object y los establece en DependencyProperty.UnsetValue , obtendrá el comportamiento que está buscando.

La sección de observaciones de la documentación de PriorityBinding describe cómo funciona con más detalle.

En SQL puedo hacer esto:

Select Coalesce(Property1, Property2, Property3, ''All Null'') as Value From MyTable

Si Property1, 2 y 3 son todos nulos, entonces obtengo ''All Null''

¿Cómo hago esto en XAML? Intenté lo siguiente, pero no tuve suerte:

<Window.Resources> <local:Item x:Key="MyData" Property1="{x:Null}" Property2="{x:Null}" Property3="Hello World" /> </Window.Resources> <TextBlock DataContext="{StaticResource MyData}"> <TextBlock.Text> <PriorityBinding TargetNullValue="All Null"> <Binding Path="Property1" /> <Binding Path="Property2" /> <Binding Path="Property3" /> </PriorityBinding> </TextBlock.Text> </TextBlock>

El resultado debería ser ''Hello World'', pero en su lugar es ''All Null''

Espero que mi pregunta sea clara.


Tendría que crear un IMultiValueConverter personalizado para hacer eso y usar un MultiBinding. PriorityBinding usa el primer enlace en la colección que produce un valor con éxito. En su caso, el enlace Property1 se resuelve inmediatamente, por lo que se usa. Como Property1 es nulo, se usa TargetNullValue.

Un convertidor como este:

public class CoalesceConverter : System.Windows.Data.IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (values == null) return null; foreach (var item in values) if (item != null) return item; return null; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

Y MultiBinding como este:

<Window.Resources> <local:Item x:Key="MyData" Property1="{x:Null}" Property2="{x:Null}" Property3="Hello World" /> <local:CoalesceConverter x:Key="MyConverter" /> </Window.Resources> <TextBlock DataContext="{StaticResource MyData}"> <TextBlock.Text> <MultiBinding Converter="{StaticResource MyConverter}"> <Binding Path="Property1" /> <Binding Path="Property2" /> <Binding Path="Property3" /> </MultiBinding> </TextBlock.Text> </TextBlock>


PriorityBinding solo busca DependencyProperty.UnsetValue para pasar al siguiente Binding . Como Property1 existe, se establece y PriorityBinding toma su valor.

Para una solución XAML pura, este Style hará el trabajo:

<TextBlock> <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Setter Property="Text" Value="{Binding Property1}" /> <Style.Triggers> <DataTrigger Binding="{Binding Property1}" Value="{x:Null}"> <Setter Property="Text" Value="{Binding Property2}" /> </DataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Property1}" Value="{x:Null}" /> <Condition Binding="{Binding Property2}" Value="{x:Null}" /> </MultiDataTrigger.Conditions> <Setter Property="Text" Value="{Binding Property3}" /> </MultiDataTrigger> <MultiDataTrigger> <MultiDataTrigger.Conditions> <Condition Binding="{Binding Property1}" Value="{x:Null}" /> <Condition Binding="{Binding Property2}" Value="{x:Null}" /> <Condition Binding="{Binding Property3}" Value="{x:Null}" /> </MultiDataTrigger.Conditions> <Setter Property="Text" Value="All Null" /> </MultiDataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock>

Aunque, es una forma un poco complicada de hacerlo, y en mi humilde opinión, no pertenece a la interfaz de usuario, sino a ViewModel.