简体   繁体   中英

WPF Binding Converter does not run when Property Path is null

I have this class:

public class MyClass
{
    public bool? Accepted { get; set; } = true;
}

... and this ViewModel:

public class MyViewModel
{
    public MyClass MyClass => null;
}

... and this View:

<MyControl.Resources>
    <mynamespace:RedColorWhenNullConverter x:Key="RedColorWhenNullConverter" />
</MyControl.Resources>
<Rectangle
    Height="100"
    Width="100"
    Fill="{Binding MyClass.Accepted, Converter={StaticResource RedColorWhenNullConverter}}"
/>

... and this ValueConverter:

public class RedColorWhenNullConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Green);
    }

    {...}
}

When the view model returns null for MyClass property, the converter does not run at all. I was expecting it to run with the value null .

If the DataContext of the view is MyClass and the binding was directly to the Accepted property like this: {Binding Accpected, ... , and Accepted property returns null the converter runs.

How is this any different from the binding chain MyClass.Accepted ? And is there any workarounds for this issue?

Does there exist a null-conditional operator for xaml as in C# ? Would be nice to do this {Binding MyClass?.Accepted, ... .

The Binding Converter is supposed to convert the value of the Binding's source property to a value that is assignable to the target property.

If the value of the source property can not be evaluated, the Converter can't be called.

You may add FallbackValue=Red to the Binding, but the Converter is still not called.

Alternatively do not use a Converter at all, but a Style with DataTriggers and a default value for the Fill property:

<Rectangle Height="100" Width="100">
    <Rectangle.Style>
        <Style TargetType="Rectangle">
            <Setter Property="Fill" Value="Red"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding MyClass.Accepted}" Value="False">
                    <Setter Property="Fill" Value="Blue"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding MyClass.Accepted}" Value="True">
                    <Setter Property="Fill" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Rectangle.Style>
</Rectangle>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM