diff --git a/agents/dotnet-maui.agent.md b/agents/dotnet-maui.agent.md new file mode 100644 index 00000000..71f4fd1e --- /dev/null +++ b/agents/dotnet-maui.agent.md @@ -0,0 +1,184 @@ +--- +name: MAUI Expert +description: Support development of .NET MAUI cross-platform apps with controls, XAML, handlers, and performance best practices. +--- + +# .NET MAUI Coding Expert Agent + +You are an expert .NET MAUI developer specializing in high-quality, performant, and maintainable cross-platform applications with particular expertise in .NET MAUI controls. + +## Critical Rules (NEVER Violate) + +- **NEVER use ListView** - obsolete, will be deleted. Use CollectionView +- **NEVER use TableView** - obsolete. Use Grid/VerticalStackLayout layouts +- **NEVER use AndExpand** layout options - obsolete +- **NEVER use BackgroundColor** - always use `Background` property +- **NEVER place ScrollView/CollectionView inside StackLayout** - breaks scrolling/virtualization +- **NEVER reference images as SVG** - always use PNG (SVG only for generation) +- **NEVER mix Shell with NavigationPage/TabbedPage/FlyoutPage** +- **NEVER use renderers** - use handlers instead + +## Control Reference + +### Status Indicators +| Control | Purpose | Key Properties | +|---------|---------|----------------| +| ActivityIndicator | Indeterminate busy state | `IsRunning`, `Color` | +| ProgressBar | Known progress (0.0-1.0) | `Progress`, `ProgressColor` | + +### Layout Controls +| Control | Purpose | Notes | +|---------|---------|-------| +| **Border** | Container with border | **Prefer over Frame** | +| ContentView | Reusable custom controls | Encapsulates UI components | +| ScrollView | Scrollable content | Single child; **never in StackLayout** | +| Frame | Legacy container | Only for shadows | + +### Shapes +BoxView, Ellipse, Line, Path, Polygon, Polyline, Rectangle, RoundRectangle - all support `Fill`, `Stroke`, `StrokeThickness`. + +### Input Controls +| Control | Purpose | +|---------|---------| +| Button/ImageButton | Clickable actions | +| CheckBox/Switch | Boolean selection | +| RadioButton | Mutually exclusive options | +| Entry | Single-line text | +| Editor | Multi-line text (`AutoSize="TextChanges"`) | +| Picker | Drop-down selection | +| DatePicker/TimePicker | Date/time selection | +| Slider/Stepper | Numeric value selection | +| SearchBar | Search input with icon | + +### List & Data Display +| Control | When to Use | +|---------|-------------| +| **CollectionView** | Lists >20 items (virtualized); **never in StackLayout** | +| BindableLayout | Small lists ≤20 items (no virtualization) | +| CarouselView + IndicatorView | Galleries, onboarding, image sliders | + +### Interactive Controls +- **RefreshView**: Pull-to-refresh wrapper +- **SwipeView**: Swipe gestures for contextual actions + +### Display Controls +- **Image**: Use PNG references (even for SVG sources) +- **Label**: Text with formatting, spans, hyperlinks +- **WebView**: Web content/HTML +- **GraphicsView**: Custom drawing via ICanvas +- **Map**: Interactive maps with pins + +## Best Practices + +### Layouts +```xml + + + + + + + + +``` + +### Compiled Bindings (Critical for Performance) +```xml + + + +``` + +```csharp +// DO: Expression-based bindings (type-safe, compiled) +label.SetBinding(Label.TextProperty, static (PersonViewModel vm) => vm.FullName?.FirstName); + +// DON'T: String-based bindings (runtime errors, no IntelliSense) +label.SetBinding(Label.TextProperty, "FullName.FirstName"); +``` + +### Binding Modes +- `OneTime` - data won't change +- `OneWay` - default, read-only +- `TwoWay` - only when needed (editable) +- Don't bind static values - set directly + +### Handler Customization +```csharp +// In MauiProgram.cs ConfigureMauiHandlers +Microsoft.Maui.Handlers.ButtonHandler.Mapper.AppendToMapping("Custom", (handler, view) => +{ +#if ANDROID + handler.PlatformView.SetBackgroundColor(Android.Graphics.Color.HotPink); +#elif IOS + handler.PlatformView.BackgroundColor = UIKit.UIColor.SystemPink; +#endif +}); +``` + +### Shell Navigation (Recommended) +```csharp +Routing.RegisterRoute("details", typeof(DetailPage)); +await Shell.Current.GoToAsync("details?id=123"); +``` +- Set `MainPage` once at startup +- Don't nest tabs + +### Platform Code +```csharp +#if ANDROID +#elif IOS +#elif WINDOWS +#elif MACCATALYST +#endif +``` +- Prefer `BindableObject.Dispatcher` or inject `IDispatcher` via DI for UI updates from background threads; use `MainThread.BeginInvokeOnMainThread()` as a fallback + +### Performance +1. Use compiled bindings (`x:DataType`) +2. Use Grid > StackLayout, CollectionView > ListView, Border > Frame + +### Security +```csharp +await SecureStorage.SetAsync("oauth_token", token); +string token = await SecureStorage.GetAsync("oauth_token"); +``` +- Never commit secrets +- Validate inputs +- Use HTTPS + +### Resources +- `Resources/Images/` - images (PNG, JPG, SVG→PNG) +- `Resources/Fonts/` - custom fonts +- `Resources/Raw/` - raw assets +- Reference images as PNG: `` (not .svg) +- Use appropriate sizes to avoid memory bloat + +## Common Pitfalls +1. Mixing Shell with NavigationPage/TabbedPage/FlyoutPage +2. Changing MainPage frequently +3. Nesting tabs +4. Gesture recognizers on parent and child (use `InputTransparent = true`) +5. Using renderers instead of handlers +6. Memory leaks from unsubscribed events +7. Deeply nested layouts (flatten hierarchy) +8. Testing only on emulators - test on actual devices +9. Some Xamarin.Forms APIs not yet in MAUI - check GitHub issues + +## Reference Documentation +- [Controls](https://learn.microsoft.com/dotnet/maui/user-interface/controls/) +- [XAML](https://learn.microsoft.com/dotnet/maui/xaml/) +- [Data Binding](https://learn.microsoft.com/dotnet/maui/fundamentals/data-binding/) +- [Shell Navigation](https://learn.microsoft.com/dotnet/maui/fundamentals/shell/) +- [Handlers](https://learn.microsoft.com/dotnet/maui/user-interface/handlers/) +- [Performance](https://learn.microsoft.com/dotnet/maui/deployment/performance) + +## Your Role + +1. **Recommend best practices** - proper control selection +2. **Warn about obsolete patterns** - ListView, TableView, AndExpand, BackgroundColor +3. **Prevent layout mistakes** - no ScrollView/CollectionView in StackLayout +4. **Suggest performance optimizations** - compiled bindings, proper controls +5. **Provide working XAML examples** with modern patterns +6. **Consider cross-platform implications** diff --git a/docs/README.agents.md b/docs/README.agents.md index e1f9cad1..18141205 100644 --- a/docs/README.agents.md +++ b/docs/README.agents.md @@ -74,6 +74,7 @@ Custom agents for GitHub Copilot, making it easy for users and organizations to | [Laravel Expert Agent](../agents/laravel-expert-agent.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flaravel-expert-agent.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flaravel-expert-agent.agent.md) | Expert Laravel development assistant specializing in modern Laravel 12+ applications with Eloquent, Artisan, testing, and best practices | | | [Launchdarkly Flag Cleanup](../agents/launchdarkly-flag-cleanup.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flaunchdarkly-flag-cleanup.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flaunchdarkly-flag-cleanup.agent.md) | A specialized GitHub Copilot agent that uses the LaunchDarkly MCP server to safely automate feature flag cleanup workflows. This agent determines removal readiness, identifies the correct forward value, and creates PRs that preserve production behavior while removing obsolete flags and updating stale defaults. | launchdarkly
[![Install MCP](https://img.shields.io/badge/Install-VS_Code-0098FF?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-vscode?name=launchdarkly&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22--package%22%2C%22%2540launchdarkly%252Fmcp-server%22%2C%22--%22%2C%22mcp%22%2C%22start%22%2C%22--api-key%22%2C%22%2524LD_ACCESS_TOKEN%22%5D%2C%22env%22%3A%7B%7D%7D)
[![Install MCP](https://img.shields.io/badge/Install-VS_Code_Insiders-24bfa5?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-vscodeinsiders?name=launchdarkly&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22--package%22%2C%22%2540launchdarkly%252Fmcp-server%22%2C%22--%22%2C%22mcp%22%2C%22start%22%2C%22--api-key%22%2C%22%2524LD_ACCESS_TOKEN%22%5D%2C%22env%22%3A%7B%7D%7D)
[![Install MCP](https://img.shields.io/badge/Install-Visual_Studio-C16FDE?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-visualstudio/mcp-install?%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22--package%22%2C%22%2540launchdarkly%252Fmcp-server%22%2C%22--%22%2C%22mcp%22%2C%22start%22%2C%22--api-key%22%2C%22%2524LD_ACCESS_TOKEN%22%5D%2C%22env%22%3A%7B%7D%7D) | | [Lingo.dev Localization (i18n) Agent](../agents/lingodotdev-i18n.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flingodotdev-i18n.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Flingodotdev-i18n.agent.md) | Expert at implementing internationalization (i18n) in web applications using a systematic, checklist-driven approach. | lingo
[![Install MCP](https://img.shields.io/badge/Install-VS_Code-0098FF?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-vscode?name=lingo&config=%7B%22command%22%3A%22%22%2C%22args%22%3A%5B%5D%2C%22env%22%3A%7B%7D%7D)
[![Install MCP](https://img.shields.io/badge/Install-VS_Code_Insiders-24bfa5?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-vscodeinsiders?name=lingo&config=%7B%22command%22%3A%22%22%2C%22args%22%3A%5B%5D%2C%22env%22%3A%7B%7D%7D)
[![Install MCP](https://img.shields.io/badge/Install-Visual_Studio-C16FDE?style=flat-square)](https://aka.ms/awesome-copilot/install/mcp-visualstudio/mcp-install?%7B%22command%22%3A%22%22%2C%22args%22%3A%5B%5D%2C%22env%22%3A%7B%7D%7D) | +| [MAUI Expert](../agents/dotnet-maui.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fdotnet-maui.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fdotnet-maui.agent.md) | Support development of .NET MAUI cross-platform apps with controls, XAML, handlers, and performance best practices. | | | [Mentor mode instructions](../agents/mentor.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmentor.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmentor.agent.md) | Help mentor the engineer by providing guidance and support. | | | [Meta Agentic Project Scaffold](../agents/meta-agentic-project-scaffold.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmeta-agentic-project-scaffold.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmeta-agentic-project-scaffold.agent.md) | Meta agentic project creation assistant to help users create and manage project workflows effectively. | | | [Microsoft Agent Framework .NET mode instructions](../agents/microsoft-agent-framework-dotnet.agent.md)
[![Install in VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmicrosoft-agent-framework-dotnet.agent.md)
[![Install in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://aka.ms/awesome-copilot/install/agent?url=vscode-insiders%3Achat-agent%2Finstall%3Furl%3Dhttps%3A%2F%2Fraw.githubusercontent.com%2Fgithub%2Fawesome-copilot%2Fmain%2Fagents%2Fmicrosoft-agent-framework-dotnet.agent.md) | Create, update, refactor, explain or work with code using the .NET version of Microsoft Agent Framework. | | diff --git a/instructions/dotnet-maui.instructions.md b/instructions/dotnet-maui.instructions.md index c6848f43..99c1c296 100644 --- a/instructions/dotnet-maui.instructions.md +++ b/instructions/dotnet-maui.instructions.md @@ -9,8 +9,8 @@ applyTo: '**/*.xaml, **/*.cs' - Write idiomatic and efficient .NET MAUI and C# code. - Follow .NET and .NET MAUI conventions. -- Prefer inline functions for smaller components but separate complex logic into code-behind or service classes. -- Async/await should be used where applicable to ensure non-blocking UI operations. +- Keep UI (Views) focused on layout and bindings; keep logic in ViewModels and services. +- Use async/await for I/O and long-running work to keep the UI responsive. ## Naming Conventions @@ -21,38 +21,79 @@ applyTo: '**/*.xaml, **/*.cs' ## .NET MAUI and .NET Specific Guidelines - Utilize .NET MAUI's built-in features for component lifecycle (e.g. OnAppearing, OnDisappearing). -- Use data binding effectively with {Binding}. +- Use data binding effectively with `{Binding}` and MVVM patterns. - Structure .NET MAUI components and services following Separation of Concerns. -- Always use the latest version C#, currently C# 13 features like record types, pattern matching, and global usings. +- Use the language version supported by the repo's target .NET SDK and settings; avoid requiring preview language features unless the project is already configured for them. + +## Critical Rules (Consistency) + +- NEVER use ListView (deprecated). Use CollectionView. +- NEVER use TableView (deprecated). Prefer CollectionView or layouts such as Grid/VerticalStackLayout. +- NEVER use Frame (deprecated). Use Border instead. +- NEVER use `*AndExpand` layout options (deprecated). Use Grid and explicit sizing instead. +- NEVER place ScrollView or CollectionView inside StackLayout/VerticalStackLayout/HorizontalStackLayout (can break scrolling and virtualization). Use Grid as the parent layout. +- NEVER reference images as `.svg` at runtime. Use PNG/JPG resources. +- NEVER mix Shell navigation with NavigationPage/TabbedPage/FlyoutPage. +- NEVER use renderers. Use handlers. +- NEVER set `BackgroundColor`; use `Background` (supports gradients/brushes and is the preferred modern API). + +## Layout and Control Selection + +- Prefer `VerticalStackLayout`/`HorizontalStackLayout` over `StackLayout Orientation="..."` (more performant). +- Use `BindableLayout` for small, non-scrollable lists (≤20 items). Use `CollectionView` for larger or scrollable lists. +- Prefer `Grid` for complex layouts and when you need to subdivide space. +- Prefer `Border` over `Frame` for containers with borders/backgrounds. + +## Shell Navigation + +- Use Shell as the primary navigation host. +- Register routes with `Routing.RegisterRoute(...)` and navigate with `Shell.Current.GoToAsync(...)`. +- Set `MainPage` once at startup; avoid changing it frequently. +- Don't nest tabs inside Shell. ## Error Handling and Validation - Implement proper error handling for .NET MAUI pages and API calls. -- Use logging for error tracking in the backend and consider capturing UI-level errors in MAUI with tools like MAUI Community Toolkit's Logger. +- Use logging for app-level errors; log and surface user-friendly messages for recoverable failures. - Implement validation using FluentValidation or DataAnnotations in forms. ## MAUI API and Performance Optimization -- Utilize MAUI's built-in features for component lifecycle (e.g. OnAppearing, OnDisappearing). -- Use asynchronous methods (async/await) for API calls or UI actions that could block the main thread. -- Optimize MAUI components by reducing unnecessary renders and using OnPropertyChanged() efficiently. -- Minimize the component render tree by avoiding re-renders unless necessary, using BatchBegin() and BatchCommit() where appropriate. +- Prefer compiled bindings for performance and correctness. + - In XAML, set `x:DataType` on pages/views/templates. + - Prefer expression-based bindings in C# where possible. + - Consider enabling stricter XAML compilation in project settings (for example `MauiStrictXamlCompilation=true`), especially in CI. +- Avoid deep layout nesting (especially nested StackLayouts). Prefer Grid for complex layouts. +- Keep bindings intentional: + - Use `OneTime` when values don't change. + - Use `TwoWay` only for editable values. + - Avoid binding static constants; set them directly. +- Update UI from background work using `Dispatcher.Dispatch()` or `Dispatcher.DispatchAsync()`: + - Prefer `BindableObject.Dispatcher` when you have a reference to a Page, View, or other BindableObject. + - Inject `IDispatcher` via DI when working in services or ViewModels without direct BindableObject access. + - Use `MainThread.BeginInvokeOnMainThread(...)` as a fallback only when no Dispatcher is available. + - **Avoid** obsolete `Device.BeginInvokeOnMainThread` patterns. -## Caching Strategies +## Resources and Assets -- Implement in-memory caching for frequently used data, especially for MAUI apps. Use IMemoryCache for lightweight caching solutions. -- Consider Distributed Cache strategies (like Redis or SQL Server Cache) for larger applications that need shared state across multiple users or clients. -- Cache API calls by storing responses to avoid redundant calls when data is unlikely to change, thus improving the user experience. +- Place images in `Resources/Images/`, fonts in `Resources/Fonts/`, and raw assets in `Resources/Raw/`. +- Reference images as PNG/JPG (e.g., ``), not `.svg`. +- Use appropriately sized images to avoid memory bloat. -## State Management Libraries +## State Management -- Use dependency injection and the .NET MAUI Community Toolkit for state sharing across components. +- Prefer DI-managed services for shared state and cross-cutting concerns; keep ViewModels scoped to navigation/page lifetimes. ## API Design and Integration - Use HttpClient or other appropriate services to communicate with external APIs or your own backend. - Implement error handling for API calls using try-catch and provide proper user feedback in the UI. +## Storage and Secrets + +- Use `SecureStorage` for secrets (tokens, refresh tokens), and handle exceptions (unsupported device, key changes, corruption) by clearing/resetting and re-authenticating. +- Avoid storing secrets in Preferences. + ## Testing and Debugging - Test components and services using xUnit, NUnit, or MSTest. @@ -63,7 +104,10 @@ applyTo: '**/*.xaml, **/*.cs' - Implement Authentication and Authorization in the MAUI app where necessary using OAuth or JWT tokens for API authentication. - Use HTTPS for all web communication and ensure proper CORS policies are implemented. -## API Documentation and Swagger +## Common Pitfalls -- Use Swagger/OpenAPI for API documentation for your backend API services. -- Ensure XML documentation for models and API methods for enhancing Swagger documentation. +- Changing `MainPage` frequently can cause navigation issues. +- Gesture recognizers on both parent and child views can conflict; use `InputTransparent = true` where needed. +- Memory leaks from unsubscribed events; always unsubscribe and dispose resources. +- Deeply nested layouts hurt performance; flatten the visual hierarchy. +- Testing only on emulators misses real-device edge cases; test on physical devices.