Add .NET MAUI Controls Expert custom agent
Creates a custom GitHub Copilot agent with deep expertise in .NET MAUI controls, their proper usage, performance optimization, and common pitfalls.
Agent Capabilities
Comprehensive Controls Reference (30+ controls)
- Activity & Status Indicators (ActivityIndicator, ProgressBar)
- Layout Controls (Border, ContentView, Frame, ScrollView)
- Shape Controls (BoxView, Ellipse, Line, Path, Polygon, Polyline, Rectangle, RoundRectangle)
- User Input Controls (Button, CheckBox, DatePicker, Editor, Entry, ImageButton, Picker, RadioButton, SearchBar, Slider, Stepper, Switch, TimePicker)
- List & Data Display (CollectionView, CarouselView, IndicatorView, BindableLayout)
- Interactive Controls (RefreshView, SwipeView)
- Display Controls (Image, Label, GraphicsView, WebView, Map)
Obsolete Controls (NEVER USE)
- ⚠️ ListView - marked as obsolete and will be deleted. Always use CollectionView instead
- ⚠️ TableView - marked as obsolete. Use custom layouts with Grid or VerticalStackLayout instead
- ⚠️ AndExpand layout options - obsolete and should never be used
Control Selection Best Practices
- Use CollectionView for all list scenarios (ListView is obsolete)
- Prefer Border over Frame for better performance (Frame still useful for shadows)
- Use Grid instead of StackLayout for complex layouts
- ⚠️ NEVER use BackgroundColor if Background property exists - always use Background
- XAML examples and usage patterns for every control
Critical Layout Warnings
- ⚠️ NEVER place ScrollView inside StackLayout controls - breaks scrolling completely (StackLayouts allow infinite space)
- ⚠️ NEVER place CollectionView inside StackLayout controls - breaks virtualization and causes severe performance issues
Data Binding Best Practices
- Compiled bindings in XAML with
x:DataType(8-20x improvement) - Expression-based compiled bindings in C# code:
- Use
SetBinding(property, static (ViewModel vm) => vm.Property)over string-basedSetBinding(property, "Property") - Use
Binding.Create(static (ViewModel vm) => vm.Property)overnew Binding("Property") - Provides type safety, compile-time error checking, IntelliSense support, and better performance
- Use
Handler Customization
- Put handler customizations inside
ConfigureHandlerscall on builder in MauiProgram.cs - Use
Mapper.AppendToMappingfor per-control customizations
Performance Critical
- Full trimming and Native AOT configuration
- Layout optimization (Grid vs StackLayout, CollectionView only)
- Profiling guidance: https://learn.microsoft.com/dotnet/maui/fundamentals/profiling
Common Pitfalls
- Don't mix Shell with NavigationPage/TabbedPage/FlyoutPage
- Prefer handlers over renderers (modern approach)
- Always set MainPage once, don't nest tabs
- CRITICAL: Image resources must be referenced as PNG (SVG only for generation)
Platform-Specific
- Conditional compilation patterns
- SecureStorage, Preferences, DeviceInfo APIs
- Handler mappers for cross-platform customization
Configuration
Located at .github/agents/maui-expert.agent.md with all tools enabled. Based on official Microsoft Learn documentation and control documentation from dotnet/docs-maui. Focused specifically on .NET MAUI controls expertise rather than general architecture patterns.
Original prompt
I want to create a MAUI coding expert Agent
Can you please create a custom agent based on everything you know about .NET MAUI and areas where users might run into issues?
The best places for you to find areas that an expert agent would be successful would be to check the conceptual docs
https://github.com/dotnet/docs-maui
Anything in those docs that are marked as "tips" or "important" will be important things to call out.
Refer to the docs here on custom agents https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/create-custom-agents
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.
@copilot this is looking good
Can you explore every single control that you can use in .NET MAUI ...
Added comprehensive coverage of every .NET MAUI control organized by category:
- Activity & Status Indicators (ActivityIndicator, ProgressBar)
- Layout Controls (Border, ContentView, ScrollView)
- Shape Controls (BoxView, Ellipse, Line, Path, Polygon, Polyline, Rectangle, RoundRectangle)
- User Input Controls (Button, CheckBox, DatePicker, Editor, Entry, ImageButton, Picker, RadioButton, SearchBar, Slider, Stepper, Switch, TimePicker)
- List Controls (CollectionView, CarouselView, IndicatorView, TableView, BindableLayout)
- Interactive Controls (RefreshView, SwipeView)
- Display Controls (Image, Label, GraphicsView, WebView, Map)
Each control includes usage guidance, XAML examples, and important tips like when to use CollectionView vs ListView, Border vs Frame, and proper image referencing. (2682cc5)
@copilot add mention of using expression-based SetBinding over string-based SetBindings and use the expression-based Binding.Create factory method over string-based new Binding("...") constructor:
// DO:
label.SetBinding(Label.TextProperty, static (ViewModel vm) => vm.FullName?.FirstName);
var binding = Binding.Create(static (ViewModel vm) => vm.FullName?.FirstName);
// DO NOT:
label.SetBinding(Label.TextProperty, "FullName.FirstName");
var binding = new Binding("FullName.FirstName");
Refer to https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/compiled-bindings?view=net-maui-10.0#compiled-bindings-in-code for more information
@copilot add mention of using expression-based
SetBindingover string-basedSetBindingsand use the expression-basedBinding.Createfactory method over string-basednew Binding("...")construc...
Added guidance on expression-based compiled bindings in C# code to the Data Binding Best Practices section. The agent now recommends using SetBinding with lambda expressions and Binding.Create factory method over string-based approaches for type safety and compile-time error checking. (a5badc0)
@copilot
For scrollview and collectionview ...
Added critical warnings for both ScrollView and CollectionView that they should NEVER be placed inside any StackLayout controls (StackLayout, HorizontalStackLayout, VerticalStackLayout). These layouts allow infinite space which breaks scrolling completely for ScrollView and invalidates virtualization for CollectionView. (0f96fe2)
@copilot can you add these instructions?
## Non‑Negotiables (Always Do This)
- Grid for page layout; no nested StackLayouts for complex UIs.
- CollectionView for lists; never ListView/TableView.
- No ScrollView or CollectionView inside any StackLayout.
- Use Background, not BackgroundColor, when available.
- Use compiled bindings everywhere (`x:DataType` on pages and DataTemplates).
- OneWay by default; avoid TwoWay unless editing.
- Centralize converters and styles in `App.xaml` or `Resources/Styles`.
- Images: reference PNGs (`logo.png`) even if SVG sources exist.
- Stick to Shell navigation;
## Instant Anti‑Pattern Detector
- StackLayout wrapping a scrollable: fix to Grid rows (`*, Auto`).
- Multiple nested layouts for simple row/column: replace with one Grid.
- Missing `x:DataType`: add it; catch binding errors at build time.
- Per‑control inline styles/brushes repeated: move to `Styles.xaml`.
- Long `CodeBehind` UI logic: move to ViewModel + Commands.
## Quick Design Review
1) Structure: Is the root a Grid with meaningful row/column definitions?
2) Lists: Are lists CollectionView inside Grid/RefreshView, not StackLayout?
3) Bindings: Does the page and each DataTemplate declare `x:DataType`?
4) Styling: Are colors/brushes/styles centralized via resources?
5) Navigation: Is Shell used consistently with routes and titles?
## Binding & Performance
- Prefer OneTime for static values; OneWay otherwise; TwoWay only for edited fields.
- Avoid bindings for constants: set them directly.
- Avoid `StringFormat` on tight loops; expose pre‑formatted properties (e.g., `FormattedTime`).
- Keep the visual tree flat; prefer Grid over nested layouts.
## Navigation & App Structure
- Shell only. Define routes; set page titles via Shell or BindingContext.
- Set `MainPage` once; no manual navigation services unless justified.
- Respect lifecycle: unsubscribe events in `OnDisappearing` if subscribed in `OnAppearing`.
## Resources, Styles, Converters
- Put converters in a shared ResourceDictionary; reference via `{StaticResource ...}`.
- Move repeated brushes and margins to styles.
- Use Border over Frame; if you need shadows, prefer Border.Shadow first.
## Diagnostics: If You See This → Do That
- Scroll stutters or memory spikes: ensure CollectionView isn’t inside StackLayout
- Colors inconsistent: migrate literals to `Resources/Styles/Colors.xaml` and `Styles.xaml`.
## When Suggesting Changes
- Be surgical: minimal edits, no broad refactors unless essential.
- Explain the anti‑pattern briefly and propose a one‑line fix.
- Prefer examples in the project’s existing style; avoid long tutorials.
Should we include pointing to the .NET MAUI Community Toolkit for converters and behaviors and such to use those instead of inventing something by itself when needed?
Not sure how far we want to go with this. If we want to also focus on the UX of a mobile app should we include recommendations for patterns to retrieve data, account for flaky connections, retries, do recommendations for libraries to use there etc?
Notes from testing the agent out in its current form, maybe we can use these to still refine.
- I need to point it to Microsoft Learn a lot. I asked it to open something in a browser window in the app and it went on to make a XAML page with a webview and show that instead of using the Essentials Browser APIs
- It doesn't know about the new SafeAreaEdges, it uses the old ones and even then has a hard time getting it right
- Selecting a pin on a map and showing a little overlay, it struggled with that
@jfversluis Initially it was suggesting things like MCT and sophisticated MVVM, but we moved away from that because it felt too advanced. I think that the goal of this agent is to focus on the obvious, baseline things rather than introducing additional abstractions, toolkits and NuGets
However, it might be useful for the agent to be aware of MAUI Essentials, since they are common and don't add extra complexity.
@jfversluis Initially it was suggesting things like MCT and sophisticated MVVM, but we moved away from that because it felt too advanced. I think that the goal of this agent is to focus on the obvious, baseline things rather than introducing additional abstractions, toolkits and NuGets
However, it might be useful for the agent to be aware of MAUI Essentials, since they are common and don't add extra complexity.
I understand, but on the other hand... I want the MAUI expert to be the expert for building a mobile app and that just happens to happen with MAUI as a framework, but leverage everything within the MAUI ecosystem to build the best possible app instead of only focusing on the product.
As a user/customer I care about having a complete, well working, maintainable app, not that it only knows about the framework itself and I still need to pull in all kinds of things manually to make the app actually useable. Imagine this being about hiring a MAUI expert from a consultancy firm being paid 200$ an hour because I want to have an app. If they will deliver just the work with the MAUI framework and be like: yeah, this is all I know, you'll have to figure out the rest to implement a great user experience and actually get it published to the store, I would be very disappointed.
Should we include pointing to the .NET MAUI Community Toolkit for converters and behaviors and such to use those instead of inventing something by itself when needed?
Not sure how far we want to go with this. If we want to also focus on the UX of a mobile app should we include recommendations for patterns to retrieve data, account for flaky connections, retries, do recommendations for libraries to use there etc?
Notes from testing the agent out in its current form, maybe we can use these to still refine.
- I need to point it to Microsoft Learn a lot. I asked it to open something in a browser window in the app and it went on to make a XAML page with a webview and show that instead of using the Essentials Browser APIs
- It doesn't know about the new SafeAreaEdges, it uses the old ones and even then has a hard time getting it right
- Selecting a pin on a map and showing a little overlay, it struggled with that
The SafeAreaEdges should have made it into the expert and probably got removed during one of the passes
Anything it gets wrong at a basic level we should add to the expert