Painlessly debugging the WPF Visual Tree in a MVVM-heavy app

Painlessly debugging the WPF Visual Tree in a MVVM-heavy app

By Tamir Dresher

Visual Studio comes with a built-in Visual Tree Visualizer which is really useful, but in order to start using it you have to find a reference to the instance of the FrameworkElement (i.e. UserControl, Window etc.) that you want to visualize.

Getting the reference to the desired FrameworkElement is especially hard if you are using proper MVVM architecture style, since most (if not all) of your code is located in the ViewModel and the ViewModel doesn’t have a reference to the View (i.e. the FrameworkElement).  When you hit a breakpoint inside your ViewModel, you have no easy way to get to the instance of your View.

OzCode comes with a great feature called Show All Instances that makes this super easy!

Suppose we have the following View which displays a list of Students:

Our XAML file is very simple, it consists of a button which is docked to the top of the view and ListView that is bound to a property called Students, the ItemTemplate for a Student consists of 3 TextBlocks for the titles and 3 TextBlocks for the values:

<UserControl x:Class="FindTheVisualTree.StudentsRecordsView"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <DockPanel LastChildFill="True">
    <Button DockPanel.Dock="Top" Command="{Binding FindTheTreeCommand}">Find The Visual Tree</Button>
    
    <ListView ItemsSource="{Binding Students}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <Border>
            <Grid>
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
              </Grid.RowDefinitions>

              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
              </Grid.ColumnDefinitions>

              <TextBlock Text="Id:" />
              <TextBlock Grid.Column="1"
                     Text="{Binding Id}" />
              <TextBlock Grid.Row="1"
                     Text="Name:" />
              <TextBlock Grid.Row="1"
                     Grid.Column="1"
                     Text="{Binding Name}" />
              <TextBlock Grid.Row="2"
                     Text="Phone:" />
              <TextBlock Grid.Row="2"
                     Grid.Column="1"
                     Text="{Binding Phone}" />
            </Grid>
          </Border>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>
  </DockPanel>
</UserControl>

 

Our ViewModel is also very simple:

public class StudentsRecordsViewModel
{
    private DelegateCommand _findTheTreeCommand;

    public StudentsRecordsViewModel()
    {
        var students = new List<Student>();
        foreach (var id in Enumerable.Range(1,30))
        {
            students.Add(new Student()
            {
                Id = id,
                Name = "Student "+id,
                Phone = string.Concat(Enumerable.Repeat(id.ToString(),9))
            });
        }
        Students = students;
    }

    public IEnumerable<Student> Students { get; set; }

    public ICommand FindTheTreeCommand
    {
        get
        {
            return _findTheTreeCommand ?? (_findTheTreeCommand = new DelegateCommand(() =>
            {
                Debugger.Break();
            }));
        }
    }
}

 

In this example I’m creating 30 students when the ViewModel is created. I've added a command that is bound to the button on the View which will trigger a break when the button is clicked:

While we are in the breakpoint, we wish to explore the Visual Tree. You can see that neither Autos nor Locals windows give any reference to the StudentsRecordsView.

To get a reference to the View we’ll use OzCode –  Show All Instances of Type:

In the “Show All Instances” window I’ll write the name of the type we’re interested in – StudentsRecordsView, and click the Show Instances button:

OzCode found the instance I'm looking for. Now we can open the WPF Tree Visualizer by clicking on the magnifying glass next to the type name:

Now we can investigate the View, see what the tree structure is, what the values of the properties inside the controls are, and even see a rendering of the UI control, at any level in the Visual Tree.

That’s it! Happy investigating!


About the author: Tamir Dresher is a Senior Consultant at CodeValue and a Lecturer on Software Engineering at Ruppin Academic Center.

Tamir specializes in .NET Technologies such as WPF, WCF, Azure, Windows Phone 8 and Windows 8 Applications, and has a lot of experience in Software Architecture and Distributed Systems.

Blog: http://blogs.microsoft.co.il/iblogger/
LinkedIn: http://www.linkedin.com/in/tamirdresher

Comments powered by Disqus