Layouts and Controls at a Glance
Grid is the most flexible layout, defining rows/columns via RowDefinitions and ColumnDefinitions with Auto, star (*), or fixed sizing, and is generally more performant than nesting multiple StackLayouts because it avoids repeated measure passes. VerticalStackLayout and HorizontalStackLayout replaced the old single StackLayout with an Orientation property, giving the layout engine a more predictable single-direction sizing pass, while FlexLayout handles wrapping content similar to CSS flexbox for adaptive multi-column arrangements.
Cricket analogy: Grid is like a scorecard's fixed rows-and-columns table (batsman, runs, balls, strike rate) that lays out precisely, while nested StackLayouts are like recalculating column widths by hand for every single entry, which is slower.
<Grid RowDefinitions="Auto,*,60" ColumnDefinitions="*,2*">
<Label Text="Header" Grid.Row="0" Grid.ColumnSpan="2" />
<CollectionView Grid.Row="1" Grid.Column="0" />
<BoxView Grid.Row="1" Grid.Column="1" Color="LightGray" />
<Button Text="Save" Grid.Row="2" Grid.ColumnSpan="2" />
</Grid>Data Binding Cheat Sheet
Enable compiled bindings by declaring x:DataType on the page or DataTemplate, then bind with {Binding PropertyName} for one-way (default for most read-only display properties) or {Binding PropertyName, Mode=TwoWay} for editable controls like Entry.Text, which is actually the default Mode for that specific property. Use {Binding ., Converter={StaticResource SomeConverter}} to transform a value before display, and x:Reference or RelativeSource bindings to bind one control's property to another sibling control's state, such as an editor's IsVisible tied to a Switch.IsToggled.
Cricket analogy: One-way binding is like a scoreboard updating from the official scorer's feed but the scorer never reads the board back, while two-way binding is like a DRS review system where the on-field umpire and TV umpire both send signals to each other.
<Entry x:DataType="vm:LoginViewModel"
Text="{Binding Username, Mode=TwoWay}"
IsVisible="{Binding IsUsernameEditable}" />
<Switch x:Name="AdvancedSwitch" />
<Entry IsVisible="{Binding Source={x:Reference AdvancedSwitch}, Path=IsToggled}" />Essential Platform APIs
The Microsoft.Maui.Essentials namespace (now built into the Microsoft.Maui.ApplicationModel and related namespaces since .NET 7) provides cross-platform wrappers for device capability access: Geolocation.GetLocationAsync() for GPS, Preferences.Set/Get for lightweight key-value storage, SecureStorage.SetAsync for encrypted credential storage (Keychain on iOS, Keystore on Android), and Connectivity.NetworkAccess for checking online status. Every capability that touches sensitive data or hardware requires a permission request via Permissions.RequestAsync<Permissions.LocationWhenInUse>() before the call, and platform manifest entries (Info.plist usage descriptions, AndroidManifest.xml permissions) must also be declared or the app will crash at runtime.
Cricket analogy: Requesting a runtime permission before using Geolocation is like a fielder needing the umpire's clearance before a substitute can take the field — skip the request and the whole play (API call) gets disallowed.
Preferences is unencrypted and synchronous-feeling but backed by platform key-value stores (NSUserDefaults, SharedPreferences) — use it for non-sensitive settings like theme choice; always use SecureStorage for tokens, passwords, or API keys.
Forgetting to add the NSLocationWhenInUseUsageDescription key to Info.plist (iOS) or the ACCESS_FINE_LOCATION permission to AndroidManifest.xml will cause Geolocation.GetLocationAsync() to throw or crash at runtime even if Permissions.RequestAsync succeeds in code — the manifest declaration is mandatory, not optional.
- Grid with RowDefinitions/ColumnDefinitions is generally the most performant layout for structured UI.
- VerticalStackLayout/HorizontalStackLayout replaced StackLayout for clearer, single-direction sizing.
- Always declare x:DataType to enable compiled bindings for both performance and compile-time safety.
- Entry.Text defaults to TwoWay binding; most display-only bindings default to OneWay.
- Use x:Reference or RelativeSource to bind one control's property to a sibling control's state.
- Preferences is for non-sensitive key-value settings; SecureStorage is for encrypted credentials/tokens.
- Runtime Permissions.RequestAsync calls must be paired with platform manifest declarations or the app crashes.
Practice what you learned
1. Which layout is generally most performant for complex structured UI in MAUI?
2. What is required on a page or DataTemplate to enable compiled bindings?
3. What is the default binding Mode for Entry.Text?
4. Which API should be used to store an OAuth access token securely in MAUI?
5. What happens if you call Geolocation.GetLocationAsync() without declaring the platform manifest usage description, even after Permissions.RequestAsync succeeds?
Was this page helpful?
You May Also Like
MAUI Best Practices
Practical guidelines for structuring, optimizing, and shipping production-quality .NET MAUI applications.
Building a To-Do App
A hands-on walkthrough of building a MAUI to-do list app with MVVM data binding and local SQLite persistence.
MAUI vs Flutter
A technical comparison of .NET MAUI and Flutter across language, rendering, performance, and ecosystem to help you choose the right cross-platform stack.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics