A button does nothing when you tap it. No crash. No exception. The markup compiles, the page renders, the button appears enabled, it just sits there.
Silent binding failures are the most time-consuming class of bug in XAML development because they give you nothing to work with.If you've built anything with XAML, you've been here. No error. No stack trace. Just a control that quietly ignores your intent.
The traditional debugging path looks like this: read the XAML, scan for typos, check the code-behind, add some debug output, rebuild, run, check output, repeat. Depending on the complexity of the page, that's 15–60 minutes of your life.
There's a faster way.
Runtime Inspection with Uno Platform App MCP
Uno Platform provides a local MCP server (App MCP) that connects your AI agent to your running application. Instead of guessing what's happening at runtime, the agent can inspect the live visual tree, check DataContext values, and read binding states directly.
Here's how that changes the debugging workflow.
A Real Example: The Missing Command
Setup
An EditProfilePage has a Save button. The page uses MVUX with a partial record model. The button is bound to a command:
<Button Content="Save" Command="{Binding SaveProfile}" />
The model has a method that should generate the command:
public partial record EditProfileModel
{
public async ValueTask SaveProfle(CancellationToken ct)
{
// save logic
}
}
The app builds. The page renders. The button appears. Nothing happens when you tap it.
1 Inspect the Running App
With the app running, ask your AI agent:
"Using App MCP, inspect the Save button on EditProfilePage. Get a visual tree snapshot focused on the Button element. Call uno_app_get_element_datacontext on the Save button. Report: Command binding value, DataContext type and instance, IsEnabled state."
2 Read the Evidence
The agent reports back:
- ✓ The Button exists in the visual tree
- ✓ IsEnabled is
true - ✓ The DataContext is a valid
EditProfileModelinstance - ✗ The Command property is null
That's the diagnosis. The DataContext is fine, the model is injected correctly. But the Command binding resolved to nothing.
3 Cross-Reference the Binding Path
Now you know exactly where to look. The XAML binds to SaveProfile. MVUX generates commands from public methods on the model, using the method name as the command name.
Look at the method name again: SaveProfle. Missing an "i."
MVUX generated a command called SaveProfle (matching the method). The XAML binds to SaveProfile. No match. No error. Just null.
4 Fix and Verify
Rename the method to SaveProfile. Rebuild. Run. Then verify:
"Using App MCP, inspect the Save button again. Confirm the Command property is now non-null. Use uno_app_pointer_click to tap the button and take a screenshot showing the result."
The agent confirms the Command resolves to a non-null IAsyncCommand. The button works.
The key insight is that uno_app_get_element_datacontext tells you the truth about runtime state. When the DataContext is valid but a specific property (like Command) is null, the problem is in the binding path, the name doesn't match what's available on the DataContext. Every time.
Without runtime inspection, you're working backwards from symptoms. With it, you're working forward from evidence.
The Pattern for Any Silent Binding Failure
This isn't specific to commands. The same approach works for any binding that silently fails:
- Inspect the element with App MCP's visual tree snapshot
- Check the DataContext with
uno_app_get_element_datacontext - Compare what the binding expects vs. what the DataContext actually provides
| DataContext | Bound Property | Diagnosis |
|---|---|---|
| Null | Any | DataContext not set — check page registration, DI, or navigation |
| Valid, wrong type | Any | Wrong model injected — check route registration |
| Valid, correct type | Null | Binding path doesn't match a property on the model |
| Valid, correct type | Has value | Binding works — problem is elsewhere (logic, not binding) |
That table covers about 90% of silent binding failures.
Binding Verification Checklist
Use this after any change that touches bindings:
Getting Started
If you want to try this workflow, you need two things:
- Uno Platform App MCP running locally, connected to your running app
- An MCP-capable AI agent (Claude Code, Codex CLI, VS Code with Copilot, etc.)
Setup takes about 5 minutes:
claude mcp add --scope user --transport stdio "uno-app" -- dotnet dnx -y uno.devserver --mcp-app
- Uno Platform MCP Tools Reference →
- MVUX Commands Documentation →
- Related: Why Your Layout Breaks on Android But Works on Windows
- Related: A Structured Way to Verify Cross-Platform UI Parity Before You Merge
Subscribe to Our Blog
Subscribe via RSS
Back to Top