'Cannot find governing FrameworkElement, Yet it works like intended (WPF)

I have a binding that gives me an error, yet everything works exactly like it should.

I have a Custom Control with it's style/template in "Generic.xaml", in the ControlTemplate I have the following code (as well as a lot of other irrelevant code for this question):

<v:ColoredImage Image="{StaticResource LoadingIcon}" Color="{StaticResource DarkBlueClick}" RenderTransformOrigin="0.5, 0.5" VerticalAlignment="Center" Width="32" Height="32" Margin="0,0,0,0" Visibility="{Binding IsBusy, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibility}}">
    <v:ColoredImage.RenderTransform>
        <RotateTransform Angle="{Binding MainViewModel.LoadAnimAngle, RelativeSource={RelativeSource TemplatedParent}}}"/> //here is the error
    </v:ColoredImage.RenderTransform>
</v:ColoredImage>

In the ViewModel.cs file for the custom control, I have this:

public MainViewModel MainViewModel { get { return MainViewModel.instance; } }

MainViewModel.instance is a static reference.

With this in code behind:

    public MainViewModel MainViewModel
    {
        get { return (MainViewModel)GetValue(MainViewModelProperty); }
        set { SetValue(MainViewModelProperty, value); }
    }

    public static readonly DependencyProperty MainViewModelProperty =
    DependencyProperty.Register("MainViewModel", typeof(MainViewModel),
    typeof(ComPortButton), new PropertyMetadata(null));

And in the page where I'm using this custom control, I bind it:

MainViewModel="{Binding MainViewModel}"

I get this error:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=MainViewModel.LoadAnimAngle; DataItem=null; target element is 'RotateTransform' (HashCode=53044787); target property is 'Angle' (type 'Double')

But, everything works. The icon is spinning like it should. I just want to get rid of the error at start. Code works, but error is annoying.

When searching for solutions to this, I didn't find any solutions for custom controls with template/style in generic, I found solutions to User Controls and I'm unsure on how to translate the fix. I know I need to do something with "ProxyElement", but none of the solutions i found explained what it is or why it works, etc, so it's hard to translate the fix to another situation that is not exactly the same situation as the solutions I found.



Solution 1:[1]

Apparently the problem occurs when you bind to RotateTransform within a Template. It had something to do with VisualTree and RenderTransform not getting "hooked up" properly until after all loading is done.

To fix it we can bind directly to RenderTransform instead of the angle attribute of RotateTransform, but in order to do that we need a ValueConverter that converts a double (angle) to RenderTransform.

Here is the converter i created:

[ValueConversion(typeof(double), typeof(RotateTransform))]
public class AngleToTransform : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        return new RotateTransform((double)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

Then change your binding, from this:

<v:ColoredImage>
   <v:ColoredImage.RenderTransform>
      <RotateTransform Angle="{Binding MainViewModel.LoadAnimAngle, RelativeSource={RelativeSource TemplatedParent}}}"/> 
   </v:ColoredImage.RenderTransform>
</v:ColoredImage>

Into This:

<v:ColoredImage RenderTransform="{Binding MainViewModel.LoadAnimAngle, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource AngleToTransform}}"/>

Now there are no more error!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 morknox