Here's a complete guide to writing clean, maintainable XAML in .NET MAUI following best practices:
1. Basic Structure
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApp.MainPage" Title="Main Page"> <!-- Page content goes here --> </ContentPage>
2. Layout Best Practices
Use Appropriate Layout Controls
<Grid RowDefinitions="Auto, *, Auto" ColumnDefinitions="*, *" RowSpacing="10" ColumnSpacing="10"> <Label Grid.Row="0" Grid.ColumnSpan="2" Text="Welcome to MyApp" HorizontalOptions="Center" FontSize="Title"/> <CollectionView Grid.Row="1" Grid.ColumnSpan="2" ItemsSource="{Binding Items}"> <!-- Item template --> </CollectionView> <Button Grid.Row="2" Grid.Column="0" Text="Cancel" Command="{Binding CancelCommand}"/> <Button Grid.Row="2" Grid.Column="1" Text="Confirm" Command="{Binding ConfirmCommand}"/> </Grid>
Use StackLayout for Simple Vertical/Horizontal Stacks
<StackLayout Spacing="15" Padding="20"> <Label Text="Username" FontAttributes="Bold"/> <Entry Placeholder="Enter username" Text="{Binding Username}"/> <Label Text="Password" FontAttributes="Bold"/> <Entry Placeholder="Enter password" IsPassword="True" Text="{Binding Password}"/> <Button Text="Login" Command="{Binding LoginCommand}"/> </StackLayout>
3. Resource Management
Define Resources at Appropriate Levels
<ContentPage.Resources> <ResourceDictionary> <Color x:Key="PrimaryColor">#512BD4</Color> <Color x:Key="SecondaryColor">#DFD8F7</Color> <Style x:Key="BaseLabelStyle" TargetType="Label"> <Setter Property="FontSize" Value="14"/> <Setter Property="TextColor" Value="{StaticResource PrimaryColor}"/> </Style> <Style x:Key="HeaderLabelStyle" TargetType="Label" BasedOn="{StaticResource BaseLabelStyle}"> <Setter Property="FontSize" Value="20"/> <Setter Property="FontAttributes" Value="Bold"/> </Style> </ResourceDictionary> </ContentPage.Resources>
4. Data Binding Best Practices
<StackLayout> <!-- Use compiled bindings for better performance --> <Label Text="{Binding WelcomeMessage, Mode=OneWay}" Style="{StaticResource HeaderLabelStyle}"/> <!-- Use x:DataType for compile-time validation --> <CollectionView x:DataType="viewmodels:ItemsViewModel" ItemsSource="{Binding Items}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="models:Item"> <Grid Padding="10"> <Label Text="{Binding Name}" FontSize="16"/> <Label Text="{Binding Description}" FontSize="14" TextColor="Gray"/> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout>
5. Visual State Manager
<StackLayout> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="{StaticResource SecondaryColor}"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <!-- Content that will respond to visual states --> </StackLayout>
6. Template Best Practices
ControlTemplate Example
<ContentPage.Resources> <ControlTemplate x:Key="CardViewTemplate"> <Frame BorderColor="{StaticResource PrimaryColor}" CornerRadius="10" Padding="15" HasShadow="True"> <StackLayout> <ContentPresenter/> <Button Text="Action" Command="{TemplateBinding BindingContext.ActionCommand}" IsVisible="{TemplateBinding BindingContext.HasAction}"/> </StackLayout> </Frame> </ControlTemplate> </ContentPage.Resources> <!-- Usage --> <ContentView ControlTemplate="{StaticResource CardViewTemplate}"> <Label Text="This is a card component" FontSize="16"/> </ContentView>
7. Accessibility
<StackLayout> <Label Text="Welcome message" SemanticProperties.HeadingLevel="Level1" SemanticProperties.Description="Welcome text for the application"/> <Image Source="logo.png" SemanticProperties.Description="Company logo" HeightRequest="100"/> <Button Text="Continue" SemanticProperties.Hint="Navigates to the next page"/> </StackLayout>
8. Complete Example Page
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewmodels="clr-namespace:MyApp.ViewModels" xmlns:models="clr-namespace:MyApp.Models" x:Class="MyApp.Views.MainPage" Title="My App" x:DataType="viewmodels:MainViewModel"> <ContentPage.Resources> <ResourceDictionary> <!-- Colors --> <Color x:Key="PrimaryColor">#512BD4</Color> <Color x:Key="SecondaryColor">#DFD8F7</Color> <Color x:Key="ErrorColor">#FF0000</Color> <!-- Styles --> <Style x:Key="BaseLabelStyle" TargetType="Label"> <Setter Property="FontSize" Value="14"/> <Setter Property="TextColor" Value="{StaticResource PrimaryColor}"/> </Style> <Style x:Key="HeaderLabelStyle" TargetType="Label" BasedOn="{StaticResource BaseLabelStyle}"> <Setter Property="FontSize" Value="20"/> <Setter Property="FontAttributes" Value="Bold"/> <Setter Property="Margin" Value="0,0,0,10"/> </Style> <Style x:Key="PrimaryButtonStyle" TargetType="Button"> <Setter Property="BackgroundColor" Value="{StaticResource PrimaryColor}"/> <Setter Property="TextColor" Value="White"/> <Setter Property="CornerRadius" Value="5"/> <Setter Property="Padding" Value="20,10"/> </Style> </ResourceDictionary> </ContentPage.Resources> <ScrollView> <Grid RowDefinitions="Auto, Auto, *, Auto" ColumnDefinitions="*" RowSpacing="20" Padding="20"> <!-- Header --> <Label Grid.Row="0" Text="Welcome to MyApp" Style="{StaticResource HeaderLabelStyle}" HorizontalOptions="Center"/> <!-- User Info --> <StackLayout Grid.Row="1" Spacing="10"> <Label Text="Username" Style="{StaticResource BaseLabelStyle}"/> <Entry Placeholder="Enter username" Text="{Binding Username}"/> <Label Text="Password" Style="{StaticResource BaseLabelStyle}"/> <Entry Placeholder="Enter password" IsPassword="True" Text="{Binding Password}"/> <Label Text="{Binding ErrorMessage}" TextColor="{StaticResource ErrorColor}" IsVisible="{Binding HasError}"/> </StackLayout> <!-- Content Area --> <CollectionView Grid.Row="2" ItemsSource="{Binding Items}" SelectionMode="Single" SelectedItem="{Binding SelectedItem}"> <CollectionView.ItemTemplate> <DataTemplate x:DataType="models:Item"> <Grid Padding="10"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="{StaticResource SecondaryColor}"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Label Text="{Binding Name}" FontSize="16"/> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> <!-- Buttons --> <Grid Grid.Row="3" ColumnDefinitions="*,*" ColumnSpacing="10"> <Button Grid.Column="0" Text="Cancel" Command="{Binding CancelCommand}"/> <Button Grid.Column="1" Text="Login" Style="{StaticResource PrimaryButtonStyle}" Command="{Binding LoginCommand}"/> </Grid> </Grid> </ScrollView> </ContentPage>
Best Practices Summary
Use appropriate layout controls - Choose Grid for complex layouts, StackLayout for simple stacks
Organize resources - Define styles, colors, and templates in resource dictionaries
Use compiled bindings (
x:DataType) for better performance and compile-time validationImplement Visual State Manager for responsive UI states
Create reusable templates with ControlTemplate and DataTemplate
Prioritize accessibility with semantic properties
Keep XAML clean by separating complex logic into view models
Use proper naming conventions for resources and elements
Optimize performance by minimizing nested layouts
Consider light/dark mode by using AppThemeBinding where needed
Remember to complement your XAML with a well-structured ViewModel and Model layer to follow the MVVM pattern properly.
No comments:
Post a Comment