Search code examples
c#wpfdata-bindinguser-controlspropertychanged

WPF UserControl Binding - OnPropertyChanged call Function


Good evening! I have read multiple threads about binding and thought I got the hang of it (at least for textBoxes, ObservableCollections, etc.). Now however, I have a bit more complicated problem and got lost somewhere:

I created a UserControl (STATUSBOX), containing labels etc. I am binding those labels like this:

 <Label x:Name="c1" x:FieldModifier="private" Grid.Column="1" 
    Grid.Row="1" Height="20" Style="{StaticResource labelTable}" 
    Width="140" Content="{Binding Path= value1}" Margin="0,0,0,0" ></Label>

In the code behind, I implemented it like that:

public String value1
    {
        get { return (String)GetValue(ValueProperty1); }
        set {
                SetValue(ValueProperty1, value); 
                //setLightColor(1, value); //[I]
            }
    }
    public static readonly DependencyProperty ValueProperty1 =
        DependencyProperty.Register("value1", typeof(string),
          typeof(UC_StatusBox_detailed), new PropertyMetadata(null));

That works just fine.

Now however, I try to add a status light which switches between green-orarnge-red. Therefore, I created a new UserControl (LAMPCONTROL) which displays part of a sprite image:

<Border x:Name="frame" x:FieldModifier="private" Width="30" Height="30" Grid.Column="0" 
    Grid.Row="0" CornerRadius="4" BorderThickness="1">
    <Rectangle Height="30" Width="30" Grid.Column="0" 
        HorizontalAlignment="Right" VerticalAlignment="Center">
            <Rectangle.Fill>
                <ImageBrush x:Name="imgBrush" x:FieldModifier="private" ViewboxUnits="Absolute" Viewbox="0,0, 30,30" ImageSource="/TestControl;component/Icons/spriteLight.png"/>
            </Rectangle.Fill>
    </Rectangle>            
</Border>

I added the following method:

private void UpdateLightStatus(Boolean statusOK)
    {
        int offset;         
        if (statusOK)
        {
            offset = 0;
        }
        else
        {
            offset = 30;
        }
        this.imgBrush.Viewbox = new Rect(offset, 0, 30, 30);
    }

That also works, if I use it "stand alone".

However if I try to implement this in my STATUSBOX, I am having trouble to get it working... I was hoping to do something like here [I] and all is done, but that does not work. In the next approach, I tried to create a DependencyProperty in the LAMPCONTROL equal to those in the STATUSBOX and add a binding in the xaml of the LAMPCONTROL and from there on I got a bit confused.

The question - in short - would be: How to call a method of a sub-UserControl from the main-UserControl when the bound property of the main-UserControl is changed?

I hope it is a bit understandable what my problem is, if more info is required, I am happy to provide that, but I didn't want to make this question even larger than it is now...

Thank you for reading all of that and best regards

Fabian


Clemens put me in the right direction. The solution is below


Solution

  • Clemens put me in the right direction. The solution is as follows:

    public static readonly DependencyProperty Value1Property =
        DependencyProperty.Register("Value1", typeof(string),
          typeof(UC_StatusBox_detailed), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender,
              new PropertyChangedCallback(OnValueChanged)));
    
    
    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    //my code here
    }