If you want to know how FindAncestor works internally, you must read the internal code. http://referencesource.microsoft.com/#PresentationFramework/Framework/MS/Internal/Data/ObjectRef.cs,6a2d9d6630cad93d
You should try and not use FindAncestor . This can be slow, plus children should not rely on the well-known words "there is somewhere a parent who has what I need."
However, FindAncestor itself may be your friend at times.
It depends on your case, but, for example, usually has a DataGridRow that uses FindAncestor to find information about a DataGrid or some other parent element.
The problem with this: IT SUPER SLOW. Let's say you have 1000 DataGridRows, and each row uses FindAncestor , plus each row has 7 columns, which themselves must go through ~ 200 elements in the logical tree. It should not be slow, DataGridRow always has the same parent DataGrid , it can be easily cached. Perhaps “one-time caching of relative sources” will become a new concept.
The concept might be this: write your own sourceSource binding, as you did. As soon as the binding is done for the first time, use the visual tree helper to find the parent of a specific type. If this is done, you can save the found parent in the direct parent attribute of attachewd like this:
var dic = myElementThatUsesRelativeSourceBinding.Parent. GetCurrentValue(MyCachedRelativeSourceParentsProperty) as Dictionary<Type, UIElement>; dic[foundType] = actualValue;
Later you will use this cache information in your search for a relative source later. Instead of accepting O (n), it will accept O (1) for the same parent element / s.
If you know that a parent always exists, you must create a binding in the code for each element that FindAncestor trying to use. This way you avoid crossing the tree.
You can also create a hybrid solution that tracks changes in the visual tree and the main cache. If a DataGridRow asks "find me relative source code of type DataGrid ", there is no reason why you need to do this all the time: you can cache it. There, OnVisualChildrenChanged is just an idea, not even 100% sure if it can be done beautifully, but this will require additional memory and a dictionary.
This can become very complicated, it goes without saying :-), but it would be great for a “side project”.
On the other hand; You should also smooth the visual tree, this will give you speed.