wpfivalueconverter

WPF IValueConverter not firing


I'm attempting to implement a value converter that will change the color of a button on a user control based on the custom "MyUserControlStatus" property of the user control "MyUserControl".

The code-behind looks like this:

Public Class MyUserControl
    Public Property MyUserControlStatus As Integer = 0
End Class

Public Class StatusIndicatorConverter
    Implements IValueConverter

    Public Function Convert(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.Convert
        Dim indicatorbrush As Brush = Brushes.Transparent
        Dim status As Integer = CType(value, Integer)
        Select Case status
            Case 0 : indicatorbrush = Brushes.Red
            Case 1: indicatorbrush = Brushes.Green
            Case 2 : indicatorbrush = Brushes.Yellow
        End Select

        Return indicatorbrush
    End Function

    Public Function ConvertBack(value As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class

The XAML looks like this:

<UserControl x:Class="MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MainApplicationName"
             xmlns:wpf="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
             mc:Ignorable="d"
             >

    <UserControl.Resources>
        <local:StatusIndicatorConverter x:Key="MyStatusIndicatorConverter"/>
    </UserControl.Resources>

                        <Button x:Name="ButtonStatusIndicator"
                                Background="{Binding Path=MyUserControlStatus, Converter={StaticResource MyStatusIndicatorConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                >
                            <Button.Resources>
                                <Style TargetType="Border">
                                    <Setter Property="Height" Value="10"/>
                                    <Setter Property="Width" Value="10"/>
                                    <Setter Property="CornerRadius" Value="10"/>
                                </Style>
                            </Button.Resources>
                        </Button>

</UserControl>

I get an empty, non-colored status. The breakpoints within the Convert function don't fire. I'm not sure what I'm doing wrong here, as all the parts seem to be in place. It should have made the button indicator red (for value=0). The expectation is that, as the MyUserControlStatus changes, the color of the indicator button will change, too, as it is bound to MyUserControlStatus and that value is converted to a color.


Solution

  • A Binding in a UserControl's XAML to one of its own properties must explicitly set the source object of the Binding, e.g. by setting the RelativeSource property.

    Setting Mode=TwoWay and UpdateSourceTrigger=PropertyChanged is however pointless. It has no effect at all in this Binding.

    Background="{Binding Path=MyUserControlStatus,
                         RelativeSource={RelativeSource AncestorType=UserControl},
                         Converter={StaticResource MyStatusIndicatorConverter}}"
    

    Besides that, the source property must fire a change notification in order to have the binding target property updated.

    It should be implemented as a dependency property:

    Public Shared ReadOnly MyUserControlStatusProperty As DependencyProperty =
        DependencyProperty.Register(
            name:="MyUserControlStatus",
            propertyType:=GetType(Integer),
            ownerType:=GetType(MyUserControl))
    
    Public Property MyUserControlStatus As Integer
        Get
            Return CType(GetValue(MyUserControlStatusProperty), Integer)
        End Get
        Set
            SetValue(MyUserControlStatusProperty, Value)
        End Set