I have a user control that shows a logo, which has a triggered animation. It has a couple of dependency properties for border and background brushes, and it all works well.
In the control's xaml, there's a line:
<GeometryDrawing Brush="{Binding Path=LogoBackgroundBrush, RelativeSource={RelativeSource AncestorType=local:Logo}, FallbackValue=Transparent}">
(and a similar line for the border)
I consume it in a form:
<Controls:Logo Height="70" LogoBackgroundBrush="Transparent" LogoBorderBrush="Transparent" />
This works to allow me to override the background brush, but when I run the app I get an initial failure to bind in the XAML Binding Failures window:
Cannot find source: RelativeSource FindAncestor, AncestorType='MyNameSpace.Wpf.Ui.Controls.Logo', AncestorLevel='1'.
(and a similar error for the border brush)
If I clear the error and keep working, it doesn't reappear; the control draws with the correct values, and changing the two dependency properties works correctly. For context, the window where it is consumed is created using (other services removed for brevity):
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<MainWindow>();
ServiceProvider = serviceCollection.BuildServiceProvider();
var startupForm = ServiceProvider.GetRequiredService<MainWindow>();
startupForm.Show();
The XAML structure looks like
<ResourceDictionary>
<Style>
<Setter.Value>
<ControlTemplate>
<Image>
<Image.Source>
<DrawingImage>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="{Binding ...}">
How do I diagnose the reason for the initial error? It doesn't seem to cause any other issues, other than bothering my OCD.
I have a user control that shows a logo, which has a triggered animation. It has a couple of dependency properties for border and background brushes, and it all works well.
In the control's xaml, there's a line:
<GeometryDrawing Brush="{Binding Path=LogoBackgroundBrush, RelativeSource={RelativeSource AncestorType=local:Logo}, FallbackValue=Transparent}">
(and a similar line for the border)
I consume it in a form:
<Controls:Logo Height="70" LogoBackgroundBrush="Transparent" LogoBorderBrush="Transparent" />
This works to allow me to override the background brush, but when I run the app I get an initial failure to bind in the XAML Binding Failures window:
Cannot find source: RelativeSource FindAncestor, AncestorType='MyNameSpace.Wpf.Ui.Controls.Logo', AncestorLevel='1'.
(and a similar error for the border brush)
If I clear the error and keep working, it doesn't reappear; the control draws with the correct values, and changing the two dependency properties works correctly. For context, the window where it is consumed is created using (other services removed for brevity):
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<MainWindow>();
ServiceProvider = serviceCollection.BuildServiceProvider();
var startupForm = ServiceProvider.GetRequiredService<MainWindow>();
startupForm.Show();
The XAML structure looks like
<ResourceDictionary>
<Style>
<Setter.Value>
<ControlTemplate>
<Image>
<Image.Source>
<DrawingImage>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Brush="{Binding ...}">
How do I diagnose the reason for the initial error? It doesn't seem to cause any other issues, other than bothering my OCD.
I found the solution to this, from this answer. Adding a name to the GeometryDrawing was enough:
<GeometryDrawing Brush="{...\>
becomes
<GeometryDrawing x:Name="logo" Brush="{...\>
I'm guessing the reason stems from what is pointed to in Clemens' comment to the original question; the visual tree isn't fully established.
From what I can tell, a partial explanation is that the name property being added causes the element to be added to the logical tree (so the element can be searched for by name presumably).
This (old) post states:
Templates are effectively late-binding; the necessary template is not attached to the control in question until the control is ready for layout. And the control is not ready for layout until it is attached to a logical tree that connects to a rendering surface at the root. It is that root-level element that initiates the rendering of all of its child elements as defined in the logical tree.