9

The following code binds a GradientStop to the Background.Color property of TemplatedParent. Everything works but I am getting a binding error in the output window:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Background.Color; DataItem=null; target element is 'GradientStop' (HashCode=6944299); target property is 'Color' (type 'Color')

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
x:Class="WpfBindingTest.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="100" Height="100">
<Window.Resources>
    <ControlTemplate x:Key="GradientTemplate" TargetType="{x:Type ContentControl}">
        <Border BorderThickness="1" BorderBrush="{TemplateBinding Background}">
            <Border.Background>
                <LinearGradientBrush  EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="{Binding Path=Background.Color, 
                        RelativeSource={RelativeSource TemplatedParent}}"  Offset="1"/>
                    <GradientStop Color="White"  Offset="0"/>
                </LinearGradientBrush>
            </Border.Background>
            <ContentPresenter/>
        </Border>
    </ControlTemplate>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <ContentControl Background="Green" Template="{StaticResource GradientTemplate}" >
        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="X" />
    </ContentControl>
</Grid>
</Window>
famousgarkin
  • 13,687
  • 5
  • 58
  • 74
McCrille
  • 91
  • 1
  • 2
  • Why not bind the background itself, versus the specific color in the gradient? – Aaron McIver Oct 07 '10 at 14:41
  • The BorderBrushis is also binded to the color (solid) so I want to set the color only once and have the gradient use the same color for gradientstop. (And I also want to know why I get an Error when it works) – McCrille Oct 13 '10 at 07:02

1 Answers1

1

I also had the same error in the Visual Studio console output.

A possible explanation and workaround for this is reported here

Basically if you use a Converter that returns a LinearGradientBrush then you don't get the error

The code is something like this

[ValueConversion(typeof(System.Windows.Media.Color), typeof(LinearGradientBrush))]
class GradientConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var brush = new LinearGradientBrush();
        var color = (Color)value;
        brush.StartPoint = new Point(0.5, 0);
        brush.EndPoint = new Point(0.5, 1);

        brush.GradientStops.Add(new GradientStop(Colors.White, 0));
        brush.GradientStops.Add(new GradientStop((Color)value, 1));

        return brush;
    }

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

And in the XAML

<Border BorderThickness="1" BorderBrush="{TemplateBinding Background}" Background="{Binding Path=Background.Color, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource gradConv}}">
Klaus78
  • 11,648
  • 5
  • 32
  • 28
  • 6
    This answer seems useful to me. However, it basically side-steps the underlying problem by doing the problematic work in code-behind. It sure would be nice to know how to get **XAML** to handle scenarios like this gracefully. (Note also that your link to "possible explanation and workaround" no longer exists...classic example of why any pertinent details should _always_ be copied into the SO answer itself, even if they exist elsewhere on the web). – Peter Duniho Jun 11 '15 at 21:58