Bindings with RalativeSource of type FindAncestor are not re-evaluated when an element moves in the visual tree
See original GitHub issue- .NET Core Version: 5.0.102
- Windows version: 10.0.19042.746
- Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
Problem description: When an element containing a binding with relative source FindAncestor is moved in the visual tree, the binding is not re-evaluated.
Expected behavior: The binding to be re-evaluated and determine the new/current relative-source ancestor.
Minimal repro: Create a WPF app that somehow hosts the following elements. For readability, layout properties have been removed.
<DockPanel>
<ContentPresenter x:Name="Parent1">
<ContentPresenter.Content>
<Border Background="{Binding Path=BorderBrush, RelativeSource={RelativeSource AncestorType={x:Type Border}}}" />
</ContentPresenter.Content>
</ContentPresenter>
</DockPanel>
<Border BorderBrush="Red">
<ContentPresenter x:Name="Parent2" />
</Border>
<Border BorderBrush="Blue">
<ContentPresenter x:Name="Parent3" />
</Border>
Create a button or similar logic that moves the content in the visual tree. Example:
object content = this.Parent1.Content;
this.Parent1.Content = null;
this.Parent2.Content = content;
Issue Analytics
- State:
- Created 3 years ago
- Reactions:5
- Comments:6
Top Results From Across the Web
WPF Binding with RelativeSource and AncestorType
Therefore, the RelativeSource AncestorType binding does not yield any result. This should be indicated by a warning in your output window.
Read more >Xamarin.Forms Relative Bindings
FindAncestor indicates the ancestor in the visual tree of the bound element. This mode should be used to bind to an ancestor control ......
Read more >Can't find the right ancestor to bind to in UI for WPF
Data Error : 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.
Read more >NoesisGUI 2.1 Changelog - Documentation
Fixed Crash in binding with RelativeSource FindAncestor when type was not resolved. Fixed Popup Closed event was raised twice for ContextMenu. Fixed Some ......
Read more >Binding ContentPane's Header to a Property in ...
Hello,. we have a problem with the headertemplate of the contentpane in a DockManager. I've tried several binding paths and ancestortypes.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I managed to fixed the issue in my case by setting x:Shared=“false” which I just learned about. The bug is still a problem, but creating a new instance rather than re-evaluating just happens to be a valid workaround in my case, but can only be applied when the object in question is in a resource dictionary which is not the case for the original issue.
This issue persists in .NET core, I am using .NET 6.0 and running into the same problems. In my case, I have data that can be displayed using different layouts. These layouts are UserControls that are displayed in a ContentControl and switched between using a DataTemplate.
I have a ContextMenu for when multiple items are selected, and would like that same contextmenu in every layout, because the layout is just UI fluff, the functionality between them should be the same. I need to bind the CommandParameter to the SelectedItems of either a DataGrid or a Listbox, depending on the layout and do stuff with those items such as deleting them as shown in this example.
When I put this ContextMenu in a resource.xaml file however, the CommandParameter binds to the SelectedItems of the first layout I right click on . When I change the layout and select different Items, the actions will still be performed on the selected items of the datagrid/listbox that is no longer there. It has not realised that the Ancestor has changed. As a sidenote, the binding of the command is also stale but that isn’t an issue as the command is the same for every layout, and inherited from a common LayoutViewModel.
The current workaround is to copy-paste the Context Menu as a resource into every layout so that it gets reinitialised when a new layout it loaded causing it to reevaluate the relative source which is a huge amount of code duplication. I really hope this issue gets looked at a second time and that this more real world example gives some context to where this would be useful in a real application.
And before you suggest to bind SelectedItems to a Property in the Viewmodel and access it that way as a workaround, that doesn’t work because of issue #3140.