Debugging a WinUI application often becomes difficult when the problem only appears while the application is already running.
The code may look correct, the debugger may show no exception, and the application may still have a UI element that is behaving differently from what you expected. A page might contain the wrong visual element, a control may have an unexpected property value, or a layout problem may only become obvious after several navigation or interaction steps.
This is where runtime inspection becomes useful.
Instead of stopping the application and reading XAML line by line, a developer can inspect the live visual tree, examine properties, and understand how the running UI is actually composed.
The new DevTools preview for WinUI is intended to make this kind of investigation easier. The important idea is not simply that another debugging window exists. The value comes from being able to inspect the application as it exists at runtime, where styles, templates, bindings, visual states, generated elements, and layout behavior have already been applied.
This article explains how to use the WinUI DevTools preview during local development, what to inspect first, how it differs from ordinary XAML debugging, and how to use it when diagnosing layout and UI behavior.
What Runtime UI Inspection Means
A WinUI application starts with the XAML and C# code you write, but the running interface is more complicated than the source files suggest.
Consider a simple control:
<Button
Content="Save"
Style="{StaticResource PrimaryButtonStyle}" />
The source code shows a Button.
At runtime, however, that button can be affected by:
- Styles
- Templates
- Theme resources
- Visual states
- Parent layout
- Data binding
- Resource inheritance
- Control properties
- Generated visual elements
- Application-level resources
- Window and page state
The result is a runtime visual tree.
The visual tree is the collection of UI elements that WinUI actually uses to construct and render the interface. Some of those elements come directly from your XAML, while others are generated internally by controls and templates.
This distinction matters when debugging.
You may inspect the XAML and see one control, but the behavior you are trying to understand may come from a child element generated by that control's template.
Runtime inspection lets you investigate the result rather than only the source.
What the WinUI DevTools Preview Is For
The WinUI DevTools preview provides runtime inspection capabilities for WinUI applications during development.
The exact capabilities available can change as the preview evolves, so you should treat it as a development diagnostic tool rather than something your production application depends on.
The useful workflow is generally:
Run WinUI application
|
v
Connect development tools
|
v
Inspect live UI
|
+-- Visual tree
+-- Properties
+-- Layout
+-- Resources
+-- Runtime state
|
v
Identify unexpected behavior
|
v
Fix source code
|
v
Run again and verify
The important distinction is that the tool inspects the running application.
You are not merely browsing the XAML file.
Why Inspecting the Live Visual Tree Helps
Suppose a developer says:
“The button has the correct Margin in XAML, but it still looks too far away from the control above it.”
Reading the XAML again may not reveal the problem.
The actual runtime hierarchy might look conceptually like this:
Page
└── Grid
└── StackPanel
├── TextBlock
├── ContentPresenter
│ └── Button
└── Border
The unexpected spacing might come from the parent StackPanel, a template-generated element, or another property applied at runtime.
A live visual tree gives you a way to locate the actual element responsible for the behavior.
This is especially useful when controls use templates because the visible UI can contain several layers that are not obvious from the original XAML.
Start With a Development Build
Runtime inspection should be performed during development or controlled testing.
Start the WinUI application from your normal development workflow and make sure the application is running under the configuration supported by the DevTools preview.
Keep the following consistent when investigating a bug:
- Windows version
- Windows App SDK version
- WinUI version
- Application build
- XAML resources
- Test data
- Window size
- Display scaling
This matters because layout behavior can change when the environment changes.
A problem that appears at 150 percent display scaling may not appear at 100 percent.
Similarly, a layout that looks correct in a small development window may behave differently when the application runs maximized.
Connect DevTools to the Running Application
The exact connection and UI steps can change while the DevTools feature is in preview, so use the current installation and preview documentation for the version of WinUI and Windows App SDK being tested.
The general process is straightforward:
1. Build the WinUI application.
2. Start the application.
3. Open the supported WinUI DevTools experience.
4. Select the running application instance.
5. Attach or connect the inspection tools.
6. Select the UI element you want to investigate.
Once connected, the important thing is to reproduce the issue before making changes.
For example, if the problem is that a dialog appears incorrectly:
Launch application
↓
Open Settings
↓
Open Account dialog
↓
Observe incorrect spacing
↓
Inspect live visual tree
This gives you a known point in time from which to investigate.
Understanding the Visual Tree
The visual tree should be treated as the runtime representation of the interface.
A simple XAML page might look like this:
<Grid>
<StackPanel>
<TextBlock Text="Customer" />
<TextBox Text="{Binding CustomerName}" />
<Button Content="Save" />
</StackPanel>
</Grid>
The source appears simple.
At runtime, controls may introduce additional visual elements through their templates.
Conceptually, you may encounter something closer to:
Grid
└── StackPanel
├── TextBlock
├── TextBox
│ └── Template-generated elements
└── Button
└── Template-generated elements
You should not assume that every generated element is something you need to modify directly.
The purpose of inspecting those elements is to understand where a property or layout behavior originates.
The source code should remain the place where you make the permanent fix.
Selecting an Element
A useful runtime inspection workflow is to select the element that visually exhibits the problem.
For example, suppose a TextBox appears too tall.
Start with the TextBox itself.
Then inspect:
- Width
- Height
- MinWidth
- MinHeight
- MaxWidth
- MaxHeight
- Margin
- Padding
- HorizontalAlignment
- VerticalAlignment
- Font properties
- Border-related properties
- Parent element
You are trying to determine whether the problem comes from the control itself or from its surrounding layout.
A useful diagnostic chain is:
Visual problem
↓
Select visible control
↓
Inspect properties
↓
Inspect parent
↓
Inspect generated template elements
↓
Find property or layout constraint
↓
Return to source code
This is much faster than changing several XAML properties and hoping the result looks better.
Investigating Layout Problems
WinUI layout is based heavily on the relationship between parent and child elements.
Two controls can have identical Width values but appear at different sizes because their parents provide different layout constraints.
For example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0"
Text="Orders" />
<ListView
Grid.Row="1" />
</Grid>
The ListView does not independently decide how much vertical space it receives.
The Grid determines the available space based on the row definitions and the available size of the window.
When the layout is wrong, inspect the parent hierarchy.
Ask:
- What size does the parent provide?
- Is the row or column constrained?
- Is the child using Auto, Star, or fixed sizing?
- Is Margin reducing the available area?
- Is MinWidth or MinHeight forcing a larger size?
- Is the control aligned differently than expected?
Runtime inspection helps answer these questions using the actual running layout rather than assumptions about what the XAML should be doing.
Debugging Unexpected Margin and Padding
Margin and Padding are easy to confuse.
Margin describes space around an element.
Padding describes space inside an element.
Consider:
<Button
Margin="20"
Padding="12"
Content="Save" />
The Margin affects the distance between the Button and surrounding elements.
The Padding affects the space between the button content and its internal boundaries.
If the button appears too far away from neighboring controls, inspect Margin and the parent layout.
If the text appears too far from the button edges, inspect Padding.
This distinction becomes particularly important when styles are applied.
A style may set a value that is not visible in the local XAML.
Inspecting Styles and Templates
Styles are one of the most common reasons a runtime value differs from what you expect.
For example:
<Style x:Key="PrimaryButtonStyle" TargetType="Button">
<Setter Property="Padding" Value="16,8" />
<Setter Property="MinHeight" Value="40" />
</Style>
A button using this style may not contain those values directly in its own XAML.
If the button looks different from another button, inspect the runtime properties and determine which values are being applied.
This is particularly useful when an application has:
- Application-level styles
- Page-level styles
- Theme resources
- Control-specific styles
- Implicit styles
- Custom control templates
Runtime inspection can reveal the result of those resource relationships.
The fix should normally be made in the appropriate resource dictionary or source XAML rather than by trying to manipulate the running element permanently.
Debugging Data-Bound Controls
Runtime inspection is also useful when the UI appears correct structurally but displays unexpected data.
Consider:
<TextBlock
Text="{Binding CustomerName}" />
If the TextBlock is empty, there are several possible causes.
The problem may be:
- The DataContext is incorrect.
- The binding path is incorrect.
- The property is null.
- The property is not notifying changes.
- The data has not loaded yet.
- A converter changed the value.
- The control is connected to a different data object than expected.
The runtime UI can help you confirm which element is actually receiving the data and whether the visual hierarchy matches your expectations.
This is especially useful in pages that contain nested controls and DataContexts.
Debugging Generated Controls
Some WinUI controls generate significant internal visual structures.
For example, controls such as ListView, TreeView, ComboBox, TextBox, and other templated controls may create additional visual elements.
You generally should not treat every generated element as application-owned UI.
Instead, use the generated hierarchy to understand behavior.
For example:
ListView
|
+-- ScrollViewer
|
+-- ItemsPresenter
|
+-- Generated item
|
+-- ContentPresenter
If scrolling or item layout behaves unexpectedly, inspecting this hierarchy can show whether the problem is related to the item itself, the ItemsPresenter, the ScrollViewer, or another part of the control structure.
The hierarchy is diagnostic evidence.
It is not an invitation to modify internal implementation details directly.
Debugging a Slow Screen
Runtime inspection is not a replacement for ETW profiling.
These tools answer different questions.
Suppose a page takes a long time to become responsive.
DevTools may help you inspect:
- Which elements exist
- How deeply nested the visual tree is
- Which controls are being generated
- Which properties are applied
- Whether unexpected elements are present
ETW can help determine:
- How much CPU the UI thread uses
- How long operations take
- Whether the thread is waiting
- Whether disk or network activity is involved
- Whether frames are taking too long
The two approaches work well together.
WinUI DevTools
|
+-- What does the UI look like at runtime?
+-- Which elements exist?
+-- Which properties are applied?
|
v
ETW / WPA
|
+-- How long does the work take?
+-- Which thread is responsible?
+-- What is the application waiting for?
This is a much stronger debugging workflow than relying on either tool alone.
Inspecting a Real Layout Problem
Consider a dashboard with three panels:
<Grid ColumnSpacing="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<local:SalesPanel Grid.Column="0" />
<local:OrdersPanel Grid.Column="1" />
<local:CustomerPanel Grid.Column="2" />
</Grid>
The developer expects all three panels to have the same width.
However, the third panel appears smaller.
Instead of immediately changing the column definitions, inspect the running visual tree.
You might discover that CustomerPanel contains a child with a large MinWidth.
That child forces the panel to request more space than expected.
The problem is therefore not necessarily the Grid.
The runtime hierarchy gives you the path:
Grid
↓
CustomerPanel
↓
Child control
↓
MinWidth
↓
Unexpected layout constraint
Now you can return to the source code and decide whether the MinWidth is intentional.
This is a much safer fix than randomly changing Grid sizing.
Inspecting Visual State Problems
WinUI controls often use visual states for interaction.
For example, a button may have different states for:
- Normal
- PointerOver
- Pressed
- Disabled
- Focused
A control that looks wrong only when hovered or focused may therefore have a state-specific property or style.
If the problem occurs only after an interaction, reproduce that exact interaction before inspecting the element.
For example:
Normal state
↓
Pointer over
↓
Select element
↓
Inspect runtime values
This can help distinguish a permanent style problem from a state-specific problem.
Inspecting a Navigation Scenario
Navigation can expose problems that are not obvious on the initial page.
Suppose the application uses several pages:
HomePage
↓
OrdersPage
↓
OrderDetailsPage
↓
Back to OrdersPage
After navigating back, the OrdersPage may contain duplicated controls, stale data, or unexpected state.
Runtime inspection can help determine whether the page was recreated or retained and whether the visual tree contains the elements you expected.
This is especially useful when a navigation problem appears only after repeated transitions.
Combine this with application lifecycle logging when the problem involves page creation and disposal.
Do Not Modify the Runtime UI as the Final Fix
Runtime inspection is diagnostic.
It should not become a substitute for maintaining the source code.
Suppose you discover that a button has an incorrect Padding value.
The correct workflow is:
Inspect runtime value
↓
Identify why value is applied
↓
Find source style/template/resource
↓
Change source
↓
Rebuild
↓
Inspect again
↓
Verify result
Avoid creating a workaround that only changes a runtime object during debugging unless the application design specifically requires dynamic behavior.
Otherwise, the next application launch will simply reproduce the original problem.
Common Problems When Using DevTools
The application does not appear
Check that:
- The application is running.
- The build is compatible with the preview tooling.
- The required Windows App SDK components are installed.
- The development tooling is using the expected version.
- The application is not running under an unsupported configuration.
Because this is a preview feature, compatibility can change between releases.
The inspected value is not what the XAML says
Look for:
- Styles
- Resource dictionaries
- Templates
- Data binding
- Visual states
- Parent layout constraints
- Runtime code that changes the property
The local XAML value is not necessarily the final runtime value.
The visual tree is larger than expected
This is normal for templated controls.
Do not assume every generated element represents unnecessary application code.
First determine whether the additional elements are part of the control template.
The layout changes when resizing
This can be expected.
Resize the window while observing the affected element and compare:
- Available size
- Alignment
- Grid definitions
- Min and Max constraints
- Responsive state changes
A layout that works at one window size may expose a constraint problem at another.
Common Mistakes
Looking only at source XAML
Source code shows what you requested.
Runtime inspection shows what the application actually created.
Both are necessary.
Treating every generated element as a bug
Templated controls naturally generate internal elements.
First understand the control template before removing or replacing anything.
Changing several properties at once
If you change Width, Margin, Padding, Alignment, and Grid definitions simultaneously, you will not know which change solved the problem.
Change one logical cause at a time.
Ignoring parent controls
A child often appears incorrect because its parent imposes a constraint.
Inspect upward in the visual tree.
Using runtime inspection for performance timing
DevTools can explain structure and runtime state, but it is not a complete performance profiler.
Use ETW, WPA, or .NET diagnostic tools when timing and resource usage are the actual problem.
Depending on preview behavior in production
Preview development tools should remain development tools.
Do not design your production architecture around an experimental debugging interface.
A Practical WinUI Debugging Workflow
A useful workflow for daily development is:
1. Reproduce the UI problem.
2. Identify the visible control that behaves incorrectly.
3. Open the WinUI DevTools preview.
4. Inspect the live visual tree.
5. Select the affected element.
6. Review its runtime properties.
7. Inspect the parent hierarchy.
8. Check styles, templates, resources, and visual states.
9. Determine the source of the unexpected value.
10. Fix the source XAML or C# code.
11. Rebuild the application.
12. Reproduce the same scenario.
13. Verify the runtime tree again.
14. Use ETW profiling if the remaining problem is timing or responsiveness.
This workflow keeps diagnosis separate from correction.
That separation is important because runtime behavior can be complicated, especially in large WinUI applications.
When to Use DevTools, Visual Studio, or ETW
The tools overlap, but they have different strengths.
Problem |
Best starting point |
Exception or code failure |
Visual Studio debugger |
Incorrect runtime property |
WinUI DevTools |
Unexpected visual hierarchy |
WinUI DevTools |
Binding-related UI issue |
WinUI DevTools + debugger |
Breakpoint and call-stack investigation |
Visual Studio |
CPU bottleneck |
ETW / WPA or Visual Studio Profiler |
UI frame performance |
ETW / WPA |
Disk or system I/O |
ETW / WPA |
Memory investigation |
Visual Studio / .NET tools / ETW |
Application startup timing |
ETW / WPA |
Thread scheduling |
ETW / WPA |
The most efficient approach is to choose the tool based on the question you are trying to answer.
Advantages and Disadvantages
Advantages:
- Lets developers inspect the running WinUI interface.
- Helps explain the difference between XAML source and runtime UI.
- Makes visual tree problems easier to investigate.
- Helps identify unexpected runtime properties.
- Useful for styles, templates, layout, and visual-state debugging.
- Complements the Visual Studio debugger.
- Works well alongside ETW performance analysis.
Disadvantages:
- Preview tooling can change between releases.
- Not every runtime behavior is exposed through visual inspection.
- Large visual trees can be difficult to navigate.
- Generated template elements can be confusing at first.
- It does not replace performance tracing.
- Some issues still require source-level debugging.
The biggest benefit comes from using DevTools to answer structural questions and other diagnostic tools to answer timing and resource questions.
Production-Oriented Checklist
Before shipping a WinUI application, use runtime inspection during development for important screens.
Check:
- Main navigation pages
- Login and authentication screens
- Large data lists
- Forms
- Dialogs
- Responsive layouts
- Custom controls
- Shared styles
- Theme resources
- Visual states
- Data-bound controls
- Navigation transitions
- Window resizing
- High-DPI configurations
For each important screen, verify that the runtime hierarchy matches the design you expect.
Also check the application at the window sizes and display scaling levels your users are likely to use.
Summary
The most useful part of WinUI DevTools is the ability to investigate the application as it actually exists while it is running.
XAML tells you what you declared. Runtime inspection helps you understand what WinUI constructed from that declaration.
That difference becomes important when debugging styles, templates, visual states, data binding, layout constraints, generated controls, and navigation behavior.
A practical approach is:
Source XAML
↓
Run application
↓
Inspect live visual tree
↓
Find unexpected runtime behavior
↓
Trace it back to source
↓
Fix source code
↓
Rebuild and verify
Use DevTools when the question is about what the UI looks like internally and why a particular element has its current state.
Use ETW and WPA when the question is about how long the application spends doing work.
Use Visual Studio when the question is about code execution, exceptions, breakpoints, and call stacks.
Combining these tools gives WinUI developers a practical way to debug both the structure and behavior of a running application before those problems reach users.
Join the conversation! Your thoughts help the community grow.