This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Windows Presentation Foundation
.NET 4.0+

WPF Base Classes - Visual

The twentieth part of the Windows Presentation Foundation Fundamentals tutorial continues the description of the base classes of the WPF layout controls investigated in earlier instalments. This article describes the Visual class.

Checking if a Control is an Ancestor

If you need to determine if two controls are linked in the hierarchy in an ancestor / descendant relationship, there are two methods that can assist. The first is IsAncestorOf. You can call this method against any Visual, passing any DependencyObject to the single parameter. If the Visual is an ancestor of the DependencyObject the method returns true. If not, it returns false.

We can demonstrate this method by adding the following code to the IAO_Click member. The code shows three message boxes, each indicating if two controls are related. The first message box shows false, because the TL label is not an ancestor of the UniformGrid. The second message is true because the UniformGrid is the direct ancestor of the TL label. The third line also shows true because the Window is an ancestor of TL, albeit not a direct one, because Window is an ancestor of the UniformGrid.

MessageBox.Show(TL.IsAncestorOf(UGrid).ToString(), "T/L is ancestor of UniformGrid?");
MessageBox.Show(UGrid.IsAncestorOf(TL).ToString(), "UniformGrid is ancestor of T/L?");
MessageBox.Show(Window.IsAncestorOf(TL).ToString(), "Window is ancestor of T/L?");

Checking if a Control is a Descendant

You can check the ancestor / descendant relationship in the opposite direction with IsDescendantOf. The parameter usage is the same as IsAncestorOf and both methods return a Boolean value. For IsDescendantOf, the return value is true when the Visual is a descendant of the DependencyObject passed as the sole argument. Try adding the following code to the IDO_Click method and running the code to see the results.

MessageBox.Show(TL.IsDescendantOf(UGrid).ToString(), "T/L is descendant of UniformGrid?");
MessageBox.Show(TL.IsDescendantOf(Window).ToString(), "T/L is descendant of Window?");
MessageBox.Show(UGrid.IsDescendantOf(TL).ToString(), "UniformGrid is descendant of T/L?");

Finding a Common Ancestor

Often two controls are not part of an ancestor / descendant relationship. However, you might need to know the closest control in the hierarchy that is an ancestor of both. This is supported by the FindCommonVisualAncestor method. You execute this against any Visual, passing a DependencyObject for the second control. The return value is the common ancestor, if one exists. If the two controls are part of separate object trees and thus have no common ancestor, the return value is null.

NB: If one of the controls is an ancestor of the other, the return value will be one of the controls.

The sample code below, which should be added to the CA_Click method, shows three examples. In the first, the common ancestor for the TL and BR controls is found. This is the UniformGrid. Its name is retrieved from the Name property, which is supplied by the FrameworkElement class, another standard base class for controls.

The second example obtains the common ancestor of the TL and BigLabel controls, which is the outer grid. The third example looks for a shared ancestor of the MainGrid and BigLabel controls. As BigLabel is a descendant of MainGrid, the grid control is returned.

var ca = TL.FindCommonVisualAncestor(BR) as FrameworkElement;
MessageBox.Show(ca.Name, "Common Visual Ancestor of T/L and B/R");

ca = TL.FindCommonVisualAncestor(BigLabel) as FrameworkElement;
MessageBox.Show(ca.Name, "Common Visual Ancestor of T/L and Big");

ca = MainGrid.FindCommonVisualAncestor(BigLabel) as FrameworkElement;
MessageBox.Show(ca.Name, "Common Visual Ancestor of Main Grid and Big");
7 July 2013