Archive for April, 2010

Most WPF developers know about the visual and logical trees of WPF. For example, a StackPanel with a Button may be made up of a StackPanel, Button, a ButtonChrome, a ContentPresenter, and a TextBlock. That’s the actual visual tree, but the logical tree is simply a StackPanel with a Button.

If you only specify your visuals in XAML, you may be overlooking another important control hierarchy. Consider this XAML:

<TabItem Header=”Tab 1″>
<TextBlock Text=”This is on Tab 1″ />
<TabItem Header=”Tab 2″>
<TextBlock Text=”This is on Tab 2″ />

The hierarchy shows that a TabControl has two TabItem controls, each with a TextBlock. This implies that the TabControl owns the TabItem controls, and each TabItem owns a TextBlock. Consider this code:

TabControl myTabControl = new TabControl();
TabItem myTabItem1 = new TabItem();
TabItem myTabItem2 = new TabItem();
TextBlock myTextBlock1 = new TextBlock() { Text = “This is on Tab 1” };
TextBlock myTextBlock2 = new TextBlock() { Text = “This is on Tab 2” };
myTabItem1.Content = myTextBlock1;
myTabItem2.Content = myTextBlock2;

Notice how flat the code looks when compared to the XAML. In the code, the same object that has a reference to the TabControl has a reference to each TabItem and TextBlock.

Imagine that you need to change the text on the TextBlock that is on Tab 2. With the XAML, you would need to walk the visual or logical trees to get a reference to the object. With the code, you already have a reference to all of the objects without walking any trees. You can simple write

myTextBlock2.Text = “New text for Tab 2”;

We really have three trees in WPF: the visual tree, the logical tree, and the ownership tree. With the code above, all of the controls have the same owner. If the owning object were a dialog, for example, the dialog may have references to every item on it. Therefore, it does not need to walk the visual or logical trees to get to its controls. The ownership tree is therefore flatter than the visual and logical trees.

I have seen developers spend unnecessary effort trying to make their business logic match the visual hierarchy of the controls. I would argue that this is counter-productive. Just because a dialog’s visual hierarchy has, say, ten levels does not mean that the business logic must have ten levels.

The business logic is mostly independent of the control-layout logic. It may not be entirely independent. For example, the dialog may not expose references to its controls to the outside world. Therefore, whoever owns the dialog does not own the controls on the dialog (unless they are intentionally exposed through a public API). Thus, the ownership hierarchy has a dialog at one level and all of the controls at a second level.

I thus recommend thinking in terms of three WPF trees: the visual tree, the logical tree, and the ownership tree.

Please feel free to comment with your own experiences.