81 .NET MAUI & Xamarin Interview Questions and Answers (2026)

One codebase, iOS, Android, macOS, and Windows — that's why teams keep betting on .NET MAUI, and why interviewers now expect you to know how it actually works. The Xamarin.Forms era is winding down, so knowing the migration story, Handlers, and Single Project structure isn't optional anymore. Walk in shaky on this and a stronger candidate takes the offer.
This post gives you 81 questions with tight, interview-ready answers and code where it helps. It runs Junior to Mid to Senior, so you build from fundamentals up through MVVM, Shell navigation, multi-targeting, and runtime performance. Read it, drill it, and walk in ready to prove you know MAUI cold.
Q1.What are the fundamental differences between Xamarin.Forms and .NET MAUI?
Xamarin.Forms and .NET MAUI?.NET MAUI is the evolution of Xamarin.Forms: same core idea (one C#/XAML UI across platforms) but rebuilt on a single project, a new Handler architecture, unified .NET runtime, and expanded desktop support.
Project structure: MAUI uses one Single Project for all platforms; Xamarin.Forms used a shared library plus separate head projects.
UI abstraction layer: MAUI uses lightweight Handlers mapping controls to native views; Xamarin.Forms used heavier Renderers.
Platform reach: MAUI adds first-class desktop (Windows via WinUI, macOS via Mac Catalyst); Xamarin.Forms was primarily mobile.
Runtime and tooling: MAUI is part of the unified .NET (6/7/8/9) with built-in DI, logging, and configuration; Xamarin ran on the older Mono-based stack and is now out of support.
Resources: MAUI centralizes images, fonts, and splash screens with build-time generation; Xamarin required per-platform assets.
Q2.What is the purpose of MainThread.BeginInvokeOnMainThread, and why is it dangerous to update the UI from a background task?
MainThread.BeginInvokeOnMainThread, and why is it dangerous to update the UI from a background task?UI frameworks require all UI updates to happen on the single main (UI) thread; MainThread.BeginInvokeOnMainThread marshals a piece of code from a background thread back onto that thread so you can safely touch UI elements.
UI is single-threaded by design: Native controls are not thread-safe; only the main thread may create, read, or modify them.
Why background UI updates are dangerous:
Updating UI off-thread throws exceptions on some platforms (iOS) and causes silent corruption or crashes on others.
Results are unpredictable: race conditions, partial rendering, or hard-to-reproduce bugs.
What BeginInvokeOnMainThread does:
Queues the delegate onto the UI thread's dispatcher so the update runs safely and asynchronously.
Use it when a callback, timer, or background Task needs to push results into the UI.
Tip: keep only the UI-touching line inside it; do the heavy work on the background thread first.
Q3.Explain the role of INotifyPropertyChanged and ObservableCollection in the MVVM pattern.
INotifyPropertyChanged and ObservableCollection in the MVVM pattern.Together they are how the View stays in sync with the ViewModel in MVVM: INotifyPropertyChanged notifies the UI when a single bound property changes, and ObservableCollection notifies it when a bound collection's items are added or removed.
INotifyPropertyChanged:
The ViewModel raises PropertyChanged with a property name; bindings for that property re-read the value and update the UI.
Without it, the View reads the value once at bind time and never sees later changes.
Usually implemented via a base class (ObservableObject) so setters call a SetProperty helper.
ObservableCollection: Implements INotifyCollectionChanged so list controls react to add/remove/clear without manual refreshes.
How they divide the work:
INotifyPropertyChanged: "this property's value changed."
ObservableCollection: "the membership of this list changed."
For an item's own fields to update in a list, that item class must also implement INotifyPropertyChanged.
Why it enables MVVM: They let the ViewModel drive the UI purely through data binding, keeping the View free of code-behind logic.
Q4.How do you implement and use a DataTemplate within a CollectionView, and what is the relationship between templates and data binding?
DataTemplate within a CollectionView, and what is the relationship between templates and data binding?You set CollectionView.ItemTemplate to a DataTemplate whose BindingContext is automatically the individual item from ItemsSource, so bindings inside the template reference each item's properties.
The relationship:
ItemsSource supplies the collection; the CollectionView stamps the template once per item and sets that item as the template's BindingContext.
Bindings like {Binding Name} resolve against the item, not the page's ViewModel.
Binding outside the item: To hit a command on the parent ViewModel from within a template, use RelativeSource with AncestorType.
Performance: CollectionView recycles realized templates as you scroll, so keep templates lightweight.
Q5.How do you detect network connectivity and handle connectivity changes using .NET MAUI Essentials?
Use Connectivity from .NET MAUI Essentials: read NetworkAccess for the current state and subscribe to the ConnectivityChanged event to react to changes.
Check current state:
Connectivity.Current.NetworkAccess returns an enum: Internet, Local, None, etc.
ConnectionProfiles tells you the transport (WiFi, Cellular) so you can gate large downloads.
Subscribe to changes:
Handle Connectivity.Current.ConnectivityChanged and inspect e.NetworkAccess to update UI or trigger sync.
Always unsubscribe to avoid leaks; do it in OnDisappearing or Dispose.
Important caveat: NetworkAccess.Internet means a route exists, not that endpoints are reachable: still handle request failures and captive portals.
Q6.Explain the difference between OneWay, TwoWay, and OneTime binding modes, and in what specific mobile UI scenario would OneTime be the most efficient choice?
OneWay, TwoWay, and OneTime binding modes, and in what specific mobile UI scenario would OneTime be the most efficient choice?The binding mode controls the direction and frequency of value flow: OneWay pushes source to target on change, TwoWay syncs both directions, and OneTime reads the source once and never listens again.
OneWay: Source updates target when the property changes; UI reflects ViewModel (default for most display controls like Label).
TwoWay:
Changes flow both ways; default for editable inputs like Entry.Text and Switch.IsToggled.
Requires listeners on both ends, so it has the most overhead.
OneTime: Reads once when BindingContext is set and drops the subscription, so no change tracking.
Where OneTime wins: Static data in a list's DataTemplate (e.g. a product ID or a label that never changes) in a large CollectionView: removing per-cell change listeners cuts memory and speeds up scrolling.
Q7.How do OnPlatform and OnIdiom work in XAML, and when would you use them to adapt your UI?
OnPlatform and OnIdiom work in XAML, and when would you use them to adapt your UI?OnPlatform and OnIdiom are XAML markup extensions that let you supply different values for a property based on the OS or the device type, so you can adapt a single UI declaratively. OnPlatform branches by platform (iOS/Android/WinUI/Mac), while OnIdiom branches by idiom (Phone/Tablet/Desktop/TV/Watch).
OnPlatform: Choose per-platform values: e.g. extra top padding on iOS, different fonts, or platform-specific colors.
OnIdiom: Choose per-device-class values: e.g. wider margins or multi-column layouts on Tablet/Desktop.
When to use:
For small property-level tweaks (spacing, sizes, images), not for deeply divergent layouts, which are better served by separate views or Visual States.
Specify x:TypeArguments so the value is converted to the right type.
Q8.How do you embed and use custom fonts and icon fonts in a .NET MAUI single project?
You drop the font file into the single project's Resources/Fonts folder, register it with an alias in MauiProgram, then reference that alias via FontFamily. Icon fonts work the same way, but you render glyphs by their Unicode code points.
Add the file: Place .ttf/.otf in Resources/Fonts; it gets build action MauiFont automatically.
Register with an alias: In CreateMauiApp call ConfigureFonts and AddFont("file.ttf", "Alias").
Use in UI: Set FontFamily="Alias" on a Label or in a style.
Icon fonts: Set the glyph as text (e.g. ) with the icon font family, or use FontImageSource for image contexts like toolbar/tab icons.
Q9.Explain the role of .NET Essentials (formerly Xamarin.Essentials) in MAUI and how it abstracts hardware features like Geolocation or Secure Storage.
Xamarin.Essentials) in MAUI and how it abstracts hardware features like Geolocation or Secure Storage..NET MAUI Essentials (the former Xamarin.Essentials, now folded into the MAUI framework) is a cross-platform API library that exposes native device and OS features through a single shared-code interface, hiding the per-platform implementation behind it.
What it covers: Hardware and OS features: Geolocation, SecureStorage, Connectivity, Preferences, sensors, and more.
How it abstracts: You call one API (e.g. Geolocation.GetLocationAsync()); internally it uses CoreLocation on iOS, LocationManager on Android, and Windows APIs.
SecureStorage example: Maps to the iOS Keychain, Android Keystore/EncryptedSharedPreferences, and Windows DataProtection: you just call SecureStorage.SetAsync().
Built into MAUI: No separate NuGet package as in Xamarin; APIs are available directly and integrate with DI via interfaces (e.g. IGeolocation) for testability.
Q10.Explain the Single Project structure in .NET MAUI. How does it handle resources like images, fonts, and splash screens differently than Xamarin.Forms?
.NET MAUI. How does it handle resources like images, fonts, and splash screens differently than Xamarin.Forms?The Single Project in .NET MAUI unifies what used to be separate head projects (one per platform) into one shared project that targets multiple platforms, with platform-specific code and resources organized by convention rather than in separate projects.
One project, many targets:
Xamarin.Forms needed a shared library plus separate Xamarin.iOS and Xamarin.Android head projects; MAUI collapses these into a single .csproj using TargetFrameworks.
Platform-specific code lives under the Platforms/ folder (Android, iOS, MacCatalyst, Windows).
Unified resource handling:
Resources go in Resources/ and are declared once as MauiImage, MauiFont, MauiSplashScreen, etc.
In Xamarin you had to duplicate assets per platform at the right density/size (e.g. drawable-hdpi, @2x/@3x) and register fonts per platform.
Images become SVG-first: A single .svg is resized/rasterized at build time into every density each platform needs, eliminating manual asset sets.
Splash screen is declarative: One MauiSplashScreen entry generates the native splash on each platform instead of hand-writing storyboards and Android themes.
Q11.What is the role of the MauiProgram class and the MauiAppBuilder, and how does this startup pattern differ from AppDelegate or MainActivity initialization in Xamarin?
MauiProgram class and the MauiAppBuilder, and how does this startup pattern differ from AppDelegate or MainActivity initialization in Xamarin?MauiProgram is the single cross-platform entry point where you configure the app: MauiAppBuilder is a fluent builder (much like ASP.NET Core's host builder) that registers services, fonts, handlers, and the root App via dependency injection, then produces a MauiApp.
Centralized, cross-platform startup: CreateMauiApp() is called once and configures everything: UseMauiApp<App>(), ConfigureFonts(), handlers, and builder.Services for DI.
Built-in dependency injection: Register services (AddSingleton, AddTransient) and constructor-inject them into pages and view models: Xamarin.Forms had no first-class DI container.
Difference from Xamarin native entry points:
Xamarin required per-platform bootstrapping: AppDelegate.FinishedLaunching on iOS and MainActivity.OnCreate on Android, each calling Forms.Init() and LoadApplication().
MAUI still has those platform entry points under Platforms/, but they simply delegate to MauiProgram.CreateMauiApp(), so configuration is written once.
Q12.Explain the concept of Multi-targeting in a single MAUI project. How does the compiler know which code to run on which platform?
Multi-targeting means one project compiles against several Target Framework Monikers (TFMs), producing a build per platform: the SDK picks the right platform APIs and code for each target using folder/filename conventions and preprocessor symbols.
Multiple TFMs in one csproj: TargetFrameworks lists targets like net9.0-android, net9.0-ios, net9.0-maccatalyst, net9.0-windows; each gets its own compilation.
Filename-based multi-targeting: Files with a platform in the name or under a Platforms/<Platform> folder (e.g. Service.Android.cs) are only compiled into that target.
Compiler symbols for inline branching: The SDK defines symbols like ANDROID, IOS, WINDOWS so #if blocks include the right code per target.
How it knows what runs where: It is resolved at compile time, not runtime: each platform binary contains only its slice of code, so there is no cross-platform runtime dispatch.
Q13.In what scenarios would you have chosen 'Xamarin Native' (Xamarin.iOS/Android) over Xamarin.Forms, and does that distinction still exist in the .NET 8/9 era?
Xamarin.iOS/Android) over Xamarin.Forms, and does that distinction still exist in the .NET 8/9 era?You chose Xamarin Native when the UI was highly platform-specific or performance/pixel-critical and code sharing was mostly business logic, and Xamarin.Forms when you wanted a shared UI across platforms with speed of development. That distinction still exists conceptually in the .NET 8/9 era, just renamed and unified under the single .NET SDK.
When Xamarin Native made sense:
Complex, platform-unique UI/UX where a shared abstraction would fight the platform.
Maximum native performance and full immediate access to platform SDKs.
You shared logic (via a .NET Standard library) but wrote UI natively per platform.
When Xamarin.Forms made sense: Form-heavy, CRUD, or line-of-business apps where one UI codebase maximizes reuse and speed.
Today (.NET 8/9):
Xamarin.Forms is succeeded by .NET MAUI (shared UI).
Xamarin Native is succeeded by .NET for Android and .NET for iOS (native bindings without MAUI's UI layer).
So the shared-UI vs native-UI choice remains: MAUI for shared, platform SDK projects for fully native.
Q14.What is the difference between ListView and CollectionView, and in what scenarios is CollectionView the better choice for performance?
ListView and CollectionView, and in what scenarios is CollectionView the better choice for performance?Both display scrolling lists, but ListView is the older Xamarin.Forms control tied to native list controls, while CollectionView is a leaner, more flexible replacement built for MAUI that virtualizes efficiently and supports multiple layouts without the overhead of cells.
ListView is cell-based:
Wraps each row in a ViewCell, which adds allocation and layout overhead per item.
Has built-in concepts like grouping headers, context actions, and pull-to-refresh baked in.
CollectionView is item-template based:
No ViewCell wrapper: the DataTemplate is rendered directly, so less overhead and smoother scrolling.
Flexible layouts via ItemsLayout (vertical, horizontal, or grid) without a separate control.
Built-in selection modes, empty-view support, and works well with ObservableCollection for incremental updates.
When CollectionView wins on performance:
Large or frequently changing data sets where cell recycling overhead matters.
Grid or horizontal layouts (carousels, tiles) that ListView can't do natively.
Rule of thumb: prefer CollectionView for new MAUI apps; reach for ListView only when you specifically need its built-in cell features and don't want to rebuild them.
Q15.Explain the App Lifecycle in .NET MAUI. What are the key events like OnStart, OnSleep, and OnResume, and how do they map to native platform lifecycles?
OnStart, OnSleep, and OnResume, and how do they map to native platform lifecycles?MAUI exposes cross-platform lifecycle events on the Application (via the Window) that abstract each platform's native lifecycle, letting you run code as the app starts, goes to the background, and returns to the foreground.
OnStart: Fires once when the app first launches; use it to initialize services or load state.
OnSleep: Fires when the app goes to the background; save state and release resources here, as the OS may kill the app.
OnResume: Fires when a backgrounded app returns to the foreground; refresh data or reconnect resources.
Mapping to native lifecycles:
On Android these correspond to OnResume/OnPause of the Activity.
On iOS they map to WillEnterForeground and DidEnterBackground of the app delegate.
Window-level and platform hooks:
MAUI also surfaces per-window events like Created, Activated, Deactivated, Stopped.
For platform-specific events not abstracted, use ConfigureLifecycleEvents() in the app builder.
Q16.What are the different service lifetimes available in the MAUI DI container, and when would you use Singleton, Transient, or Scoped in a mobile app context?
Singleton, Transient, or Scoped in a mobile app context?The MAUI DI container (the standard Microsoft.Extensions.DependencyInjection) offers three lifetimes: Singleton (one instance for the app), Transient (a new instance every resolve), and Scoped (one instance per scope), and the mobile context changes how you think about each.
Singleton:
One shared instance for the app's lifetime; ideal for stateless services, HTTP clients, caches, and app-wide state.
Watch for memory leaks: a singleton holding references keeps them alive the whole session.
Transient: New instance every time it's resolved; good for lightweight, stateful objects like ViewModels or pages you want fresh.
Scoped:
One instance per created scope; on mobile there's no per-request scope like ASP.NET, so it's less common.
Behaves like a singleton unless you explicitly create scopes (e.g. per-page scopes with IServiceScopeFactory).
Practical guidance for mobile: Singleton for services (data access, navigation, connectivity); Transient for pages and their ViewModels so navigation gives fresh state.
Q17.How has Dependency Injection changed from Xamarin.Forms to .NET MAUI, and why is the built-in .NET DI container preferred over the old DependencyService.Get<T>()?
DependencyService.Get<T>()?Xamarin.Forms shipped its own simple service locator, DependencyService, while .NET MAUI adopts the standard Microsoft.Extensions.DependencyInjection container configured on the MauiAppBuilder, giving true constructor injection and lifetime management.
The old DependencyService.Get<T>() approach:
A service locator: classes pull dependencies, hiding what they actually need.
No lifetime control beyond a basic singleton flag; no constructor injection.
Harder to test because dependencies are fetched statically rather than passed in.
The MAUI built-in container:
Register services in MauiProgram with builder.Services.AddSingleton/AddTransient/AddScoped.
Supports true constructor injection into pages and ViewModels.
Same container as the rest of .NET, so it's familiar, testable, and works with the ecosystem (logging, HTTP factory, options).
Why it's preferred: Explicit dependencies, proper lifetimes, and easy mocking make code cleaner and unit-testable.
Q18.How do you prevent 'UI Thread Blocking' when performing long-running tasks, and what is the role of MainThread.BeginInvokeOnMainThread?
MainThread.BeginInvokeOnMainThread?You keep the UI thread free by moving long-running work off it (with async/await for I/O or Task.Run for CPU work), then use MainThread.BeginInvokeOnMainThread only to push the results back onto the UI thread.
Use async/await for I/O-bound work:
Awaiting network or file calls releases the UI thread so the app stays responsive.
Avoid .Result or .Wait(), which block the thread and can deadlock.
Use Task.Run for CPU-bound work: Offloads heavy computation to a threadpool thread instead of freezing the UI.
Role of MainThread.BeginInvokeOnMainThread:
Because background threads can't touch UI, it marshals the final UI update back to the main thread.
When using data-bound properties, updates from a background thread often need this too (except collection changes handled by the framework).
Pattern: do the work off-thread, then re-enter the UI thread just to update controls.
Q19.Explain the strategy for unit testing a ViewModel and how you mock platform-specific services registered in the DI container.
A ViewModel is testable precisely because it holds no UI: you inject its dependencies as interfaces, replace them with mocks in the test, then assert on the ViewModel's properties and commands. Platform-specific services are abstracted behind interfaces so tests never touch real device APIs.
Design for testability first:
Depend on interfaces (IGeolocation, IDataService) injected via the constructor, never concrete platform types.
Keep the ViewModel free of direct calls to static MAUI APIs.
Mock the dependencies:
Use a mocking library (Moq, NSubstitute) to create fakes that return canned data.
Inject the mocks directly in the test; no DI container is needed for a unit test.
Assert observable behavior: Execute a command, then verify property values, PropertyChanged events, and that the mock was called as expected.
Handle threading: Abstract MainThread behind an interface (e.g. IDispatcher) so tests aren't blocked by the missing UI thread.
Q20.How do Triggers and Behaviors differ in XAML, and when would you use a Behavior instead of a Trigger?
Triggers and Behaviors differ in XAML, and when would you use a Behavior instead of a Trigger?Both attach reusable logic to XAML controls, but a Trigger responds declaratively to property/event/data changes to set properties or run actions, while a Behavior is a reusable C# class you attach to a control to add richer, stateful, or complex logic that triggers can't express.
Triggers are declarative:
Types include Trigger (property), DataTrigger, EventTrigger, and MultiTrigger.
Best for simple condition-to-setter mappings (e.g. change color when IsFocused is true).
Behaviors are code-based:
Derive from Behavior<T> and override OnAttachedTo/OnDetachingFrom to hook events and manage state.
Can hold fields, expose BindableProperty inputs, and encapsulate reusable interactive logic.
When to choose a Behavior:
Logic too complex for a setter: input validation, masking, or event-to-command wiring.
You need reusable, unit-testable code shared across many controls.
You want to keep code-behind clean while adding real behavior in an MVVM-friendly way.
Rule of thumb: simple visual/state reaction, use a Trigger; anything requiring real C# logic or reuse, use a Behavior.
Q21.What is a ResourceDictionary, and how do implicit styles differ from explicit (keyed) styles in MAUI?
ResourceDictionary, and how do implicit styles differ from explicit (keyed) styles in MAUI?A ResourceDictionary is a key/value store of reusable resources (styles, colors, converters, templates) scoped to an element, page, or the whole app. Implicit styles apply automatically to every element of a matching type, while explicit styles target only elements that reference them by key.
ResourceDictionary basics:
Lives in Resources on an element, Page, or App.xaml; lookup walks up the visual tree so app-level resources are global.
Referenced with {StaticResource Key} (resolved once) or {DynamicResource Key} (re-resolved when the resource changes, useful for theming).
Explicit (keyed) styles:
Defined with an x:Key and applied only where you set Style="{StaticResource Key}".
Opt-in: gives you precise control over which controls get the style.
Implicit styles:
Have a TargetType but no x:Key; automatically apply to every element of that exact type in scope.
Great for app-wide defaults (all Buttons), but they don't apply to derived types unless ApplyToDerivedTypes is true.
Precedence: a local value or explicit style overrides an implicit style, which overrides theme/default values.
Q22.How does CollectionView achieve UI virtualization and view recycling, and why does that matter for large lists?
CollectionView achieve UI virtualization and view recycling, and why does that matter for large lists?CollectionView only creates enough item views to fill the visible viewport (plus a small buffer) and recycles those views as you scroll, rebinding new data to them instead of instantiating a view per item. This keeps memory and layout cost roughly constant regardless of list size.
Virtualization:
Backed by native virtualizing containers (RecyclerView on Android, UICollectionView on iOS), so off-screen items are never realized.
Memory stays bounded even for thousands of items.
View recycling:
When an item scrolls off screen, its view is reused for an incoming item; the BindingContext is swapped rather than rebuilding the visual tree.
Because views are reused, never store per-item state in the view: rely on bindings so recycled cells show correct data.
Why it matters:
The old ListView had recycling issues and per-cell overhead; CollectionView scrolls smoothly with large data.
Use ObservableCollection for incremental updates and RemainingItemsThreshold for paging/infinite scroll.
Pitfalls: heavy DataTemplates hurt scroll performance; keep templates shallow, and use a DataTemplateSelector carefully since mismatched template types break recycling.
Q23.Why are async void event handlers acceptable for UI events but dangerous elsewhere in a MAUI app?
async void event handlers acceptable for UI events but dangerous elsewhere in a MAUI app?async void is only acceptable for event handlers because event signatures require a void return; elsewhere it's dangerous because the caller can't await it and exceptions escape onto the synchronization context instead of being catchable, often crashing the app.
Why UI events tolerate it:
Handlers like Clicked have a fixed (object sender, EventArgs e) void signature, so async void is the only way to await inside them.
They run on the UI thread's sync context, so continuations return to the UI thread as expected.
Why it's dangerous elsewhere:
You can't await it: the caller has no Task to observe completion or failure, breaking sequencing.
An unhandled exception in an async void method is re-thrown on the sync context and typically crashes the process instead of bubbling to a caller's try/catch.
It's untestable and uncomposable.
Best practices:
Prefer async Task everywhere except event handlers; in MVVM use AsyncRelayCommand so command execution is awaited and errors surfaced.
Wrap the body of async void handlers in try/catch so exceptions don't escape.
Q24.How do you implement platform-specific code in .NET MAUI using partial classes and methods instead of the old DependencyService?
DependencyService?MAUI's modern approach uses partial classes/methods split across platform folders: you declare a shared API in the common code and provide a per-platform implementation in Platforms/Android, Platforms/iOS, etc. The compiler stitches the right implementation in, avoiding the runtime lookup and registration overhead of DependencyService.
How it works:
Define a shared partial class with a partial method signature in the common project.
Provide the method body in a same-named partial class under each Platforms/* folder; MAUI's multi-targeting only compiles the matching folder per target.
Why it beats DependencyService:
Compile-time resolution: no reflection, no [assembly: Dependency] registration, and errors surface at build time.
Cleaner API: callers just use the class directly, no DependencyService.Get<T>().
Alternatives for DI: For injectable services, register a shared interface with a platform implementation in the built-in MauiAppBuilder container instead.
Q25.What is the purpose of "Conditional Compilation" (#if IOS, #if ANDROID) and when should it be avoided in favor of other patterns?
#if IOS, #if ANDROID) and when should it be avoided in favor of other patterns?Conditional compilation uses preprocessor directives to include or exclude code per target platform at build time; the compiler defines symbols like ANDROID, IOS, and WINDOWS for each head. It's ideal for small, unavoidable platform divergences but becomes a maintenance hazard when overused.
What it does:
Code inside #if ANDROID ... #endif only compiles for that target, so you can call native APIs from shared files without breaking other platforms.
Symbols come from the multi-targeted TargetFrameworks.
Good uses: A few lines of genuinely platform-only code, or guarding a namespace that exists on only one platform.
When to avoid it:
Large blocks scattered across files: hard to read, only one branch is compiled/analyzed at a time so the others silently rot.
IDE tooling, refactoring, and IntelliSense only see the active symbol set, hiding bugs in inactive branches.
Preferred alternatives:
Partial classes/methods in Platforms/* folders for clean per-platform implementations.
Runtime checks with DeviceInfo.Platform, or OnPlatform in XAML for simple value differences.
Interfaces with DI-registered platform implementations for larger behavioral splits.
Q26.What is the difference between placing platform-specific code in the Platforms/ folder versus using the .Android.cs or .iOS.cs naming convention?
Platforms/ folder versus using the .Android.cs or .iOS.cs naming convention?Both approaches target platform-specific code, but the Platforms/ folder is MAUI's default convention (folder-based, always excluded per-platform by the SDK), while filename suffixes like .Android.cs let you keep platform variants of a type next to your shared code using multi-targeting filename conventions.
Platforms/ folder:
The default single-project layout: Platforms/Android, Platforms/iOS, etc.
The project file auto-excludes each folder from builds that don't target it, so files only compile for their platform.
Best for platform entry points and things that don't map to a shared type (MainActivity, AppDelegate, manifests).
Filename suffix convention:
Files like MyService.Android.cs and MyService.iOS.cs compile only for their matching platform, with MyService.cs as a shared/partial base.
Ideal for partial classes: one logical type with a shared contract and per-platform implementations sitting together.
Choosing between them:
Use the folder for platform boot/config and native-only files; use suffixes when you want cohesive per-platform implementations of the same abstraction near your business code.
They're complementary and both driven by the same MSBuild multi-targeting rules.
Q27.Explain the MVVM Toolkit (CommunityToolkit.Mvvm) and its use of Source Generators. How do attributes like [ObservableProperty] and [RelayCommand] change the way you write ViewModels?
CommunityToolkit.Mvvm) and its use of Source Generators. How do attributes like [ObservableProperty] and [RelayCommand] change the way you write ViewModels?The MVVM Toolkit (CommunityToolkit.Mvvm) is a fast, lightweight MVVM library that uses Roslyn Source Generators to write boilerplate for you at compile time: you annotate fields and methods, and it generates the observable properties and commands, so your ViewModels stay tiny and fully AOT-friendly.
Source Generators:
Code is generated during compilation (no runtime reflection), giving good performance and trimming/AOT compatibility.
Your class must be partial so the generated half can be merged in.
[ObservableProperty]:
Put it on a private field; the generator creates a public property with full INotifyPropertyChanged raising.
Supports [NotifyPropertyChangedFor] for dependent properties and [NotifyCanExecuteChangedFor] to refresh commands.
[RelayCommand]:
Put it on a method; the generator produces an ICommand property (e.g. method Save becomes SaveCommand).
Handles async methods (returns IAsyncRelayCommand) and CanExecute wiring automatically.
Base class: Inherit ObservableObject (or ObservableValidator) for the underlying change-notification plumbing.
Q28.What is the difference between an ObservableCollection and a regular List in the context of a MAUI CollectionView, and what are the thread safety limitations of ObservableCollection?
ObservableCollection and a regular List in the context of a MAUI CollectionView, and what are the thread safety limitations of ObservableCollection?An ObservableCollection<T> raises change notifications when items are added or removed, so a CollectionView bound to it updates automatically; a plain List<T> has no notifications, so the UI won't reflect add/remove changes after the initial bind.
Why ObservableCollection updates the UI: It implements INotifyCollectionChanged, which the CollectionView listens to and re-renders incrementally.
Why List doesn't:
No change events, so adding/removing items leaves the view stale unless you reset the whole ItemsSource.
A List is fine for static data that never changes after binding, and is cheaper.
Important limits: Property changes still need INotifyPropertyChanged on the item itself; ObservableCollection only signals collection membership changes, not per-item property edits.
Thread safety:
ObservableCollection is not thread-safe: modifying it from a background thread raises change events off the UI thread and throws or corrupts the view.
Marshal mutations back to the UI thread (MainThread.BeginInvokeOnMainThread), or build the data off-thread and assign once.
Q29.Explain the MVVM pattern as it applies to XAML frameworks and how INotifyPropertyChanged and ICommand facilitate separation of concerns.
INotifyPropertyChanged and ICommand facilitate separation of concerns.MVVM (Model-View-ViewModel) splits UI (View) from state and logic (ViewModel) so XAML binds to properties and commands instead of the code-behind manipulating controls directly. INotifyPropertyChanged pushes state changes to the UI, and ICommand surfaces user actions as bindable objects, keeping the View passive.
Three layers:
Model: domain data and business rules, UI-agnostic.
View: XAML and minimal code-behind; declares bindings only.
ViewModel: exposes bindable state and commands, mediates with the Model.
INotifyPropertyChanged enables state sync: Raising PropertyChanged in a setter tells the binding engine to refresh the bound control, so the View updates without knowing the property changed.
ICommand enables action binding:
Bind Button.Command to a command instead of a Clicked event handler, so logic lives in the ViewModel.
CanExecute lets the control auto enable/disable itself.
Why it separates concerns: ViewModel has no reference to controls, so it is unit-testable and the View is swappable.
In MAUI, CommunityToolkit.Mvvm generates this boilerplate via [ObservableProperty] and [RelayCommand].
Q30.Explain the difference between StaticResource and DynamicResource. In what specific mobile scenario is DynamicResource required?
StaticResource and DynamicResource. In what specific mobile scenario is DynamicResource required?Both look up a value in a ResourceDictionary, but StaticResource resolves once at load time, while DynamicResource keeps a live link and re-applies the value whenever the resource entry changes.
StaticResource:
Resolved a single time during XAML parsing; the resource must exist before it is referenced.
Faster and lighter (no ongoing tracking); the default choice.
DynamicResource:
Holds a reference by key; if you replace the value in the dictionary at runtime, every consumer updates automatically.
Slightly heavier due to change tracking.
The mobile scenario requiring DynamicResource: Runtime theme switching (light/dark or user-selected themes): you swap the merged dictionary or update color keys, and DynamicResource-bound colors repaint instantly without recreating pages.
Q31.Explain the difference between a ControlTemplate and a DataTemplate, and when would you use one over the other to modify a component's look?
ControlTemplate and a DataTemplate, and when would you use one over the other to modify a component's look?A ControlTemplate redefines the internal visual structure of a control itself, while a DataTemplate defines how a piece of data is displayed. Use a control template to reskin a control; use a data template to shape items of a collection or content bound to a model.
ControlTemplate:
Replaces a control's chrome/layout; often used with ContentView or TemplatedView and ContentPresenter.
Uses TemplateBinding to bind to the templated parent's properties.
Example: give every page a custom header/footer shell or restyle a button's structure.
DataTemplate:
Describes the visual for a data object; its BindingContext is the data item.
Used by CollectionView, ListView, CarouselView, or BindableLayout.
Choosing between them:
Changing what the control looks like structurally: ControlTemplate.
Changing how each data record renders: DataTemplate.
Q32.Explain the purpose of a DataTemplateSelector and how it allows for dynamic UI based on the underlying data type.
DataTemplateSelector and how it allows for dynamic UI based on the underlying data type.A DataTemplateSelector lets you pick a different DataTemplate per item at runtime, so a heterogeneous collection can render each item differently based on its type or property values.
How it works:
Subclass DataTemplateSelector and override OnSelectTemplate(object item, BindableObject container).
Inspect the item and return the appropriate template you exposed as properties.
Where it plugs in: Assign the selector to CollectionView.ItemTemplate instead of a single template; the control calls it once per item.
Typical uses: A chat feed showing incoming vs. outgoing message bubbles, or a feed mixing images, text, and ads.
Constraints: Return values should be stable per item type to keep view recycling efficient; don't return a brand-new template instance each call.
Q33.What is .NET MAUI Shell, and what advantages does it provide over traditional NavigationPage or TabbedPage structures?
NavigationPage or TabbedPage structures?.NET MAUI Shell is an application container that provides a single-page app structure with built-in flyout, tabs, URI navigation, and search, reducing the boilerplate of wiring up navigation manually.
What it gives you:
A described UI hierarchy via FlyoutItem, Tab, and ShellContent in one place.
Built-in flyout menu and bottom/top tabs without custom TabbedPage plumbing.
Advantages over NavigationPage/TabbedPage:
URI-based routing enables deep links and decouples navigation from page references.
Lazy page creation: routed pages are instantiated on navigation, improving startup.
Centralized styling of the chrome (bars, tabs) and less nested-page boilerplate.
When not to use it: Very simple apps or highly bespoke navigation may be simpler with a plain NavigationPage.
Q34.What are "Commanding" and "Parameter Passing" in MAUI? How do you pass data between ViewModels during Shell navigation?
Commanding is binding user actions to ICommand objects on the ViewModel instead of event handlers, and parameter passing supplies data to those commands via CommandParameter. Between ViewModels during Shell navigation, you pass data through Shell's query parameters.
Commanding:
Bind Command to an ICommand; the MVVM Toolkit's [RelayCommand] generates one from a method.
CanExecute controls whether the bound control is enabled.
Parameter passing: CommandParameter feeds a value into the command's execute method (e.g. the tapped item).
Between ViewModels in Shell:
In a command, call GoToAsync with a dictionary of parameters.
The destination ViewModel receives them via [QueryProperty] or IQueryAttributable.
For truly decoupled cross-ViewModel messaging (not navigation), use WeakReferenceMessenger.
Q35.Compare .NET MAUI Shell navigation to the traditional NavigationPage approach. What are the tradeoffs in terms of complexity and flexibility?
NavigationPage approach. What are the tradeoffs in terms of complexity and flexibility?Shell gives you a centralized, URI-based navigation model with a built-in app skeleton (flyout, tabs), while NavigationPage is a lower-level stack you build and push manually. Shell trades some flexibility for far less boilerplate on typical apps.
Shell navigation:
Routes are registered and navigated with URIs via GoToAsync("//route"), supporting relative/absolute paths and query parameters.
Provides flyout, bottom/top tabs, and back-button behavior out of the box with a single AppShell definition.
Great for standard app shapes; less control when you need highly custom or deeply nested stacks.
NavigationPage (traditional):
You manage the stack imperatively with PushAsync / PopAsync and wire up navigation containers yourself.
More flexible for bespoke flows, but more boilerplate and manual coordination of tabs/flyout.
Tradeoff summary:
Shell: less complexity, faster to build, opinionated structure.
NavigationPage: maximum control, but you own the plumbing.
Q36.What is the benefit of using IQueryAttributable for receiving navigation parameters?
IQueryAttributable for receiving navigation parameters?Implementing IQueryAttributable lets a page or view model receive all Shell query parameters in one strongly-controlled callback, giving you a single place to apply them rather than relying on scattered property setters.
Single entry point: The ApplyQueryAttributes(IDictionary<string, object>) method delivers every parameter at once, so you can coordinate related values together.
Works well in the view model: Keeps navigation-parameter handling in the MVVM layer instead of code-behind, aiding testability.
Alternative to [QueryProperty]: Attributes bind one query key to one property; IQueryAttributable is better when you need custom logic, decoding, or to handle several params atomically.
Handles complex/encoded values: You control parsing and can decode URL-escaped strings yourself.
Q37.What is the difference between modal and non-modal (push/pop) navigation, and when would you use PushModalAsync?
PushModalAsync?Non-modal (push/pop) navigation adds pages to a stack that keeps the navigation bar and back button, while modal navigation presents a page on top that interrupts the flow and must be explicitly dismissed. Use PushModalAsync when you need the user to complete or cancel a task before continuing.
Push/pop (non-modal):
Uses PushAsync / PopAsync on the navigation stack; keeps the nav bar and lets users navigate back naturally.
Best for hierarchical drill-down flows (list to detail).
Modal:
Uses PushModalAsync / PopModalAsync; presents on a separate modal stack, typically without the standard back button.
Signals a focused, self-contained task the user must finish or dismiss.
When to use modal:
Login prompts, forms, or dialogs where you want to block the underlying context until done.
Note: in Shell you use GoToAsync and can mark routes to present modally.
Q38.How do flyout and tab structures work in Shell, and how do you configure them?
In Shell, you declare your app's structure in AppShell.xaml using FlyoutItem, TabBar, and Tab elements: a flyout is the slide-out side menu, and tabs group pages horizontally at the top or bottom.
Flyout:
Defined with FlyoutItem entries; controlled via Shell.FlyoutBehavior (Flyout, Disabled, Locked).
Customize the header/menu with Shell.FlyoutHeader and MenuItem.
Tabs:
A TabBar creates bottom tabs; multiple Tab elements under one item create top tabs.
Each ShellContent points to a page via ContentTemplate.
Combining them: A FlyoutItem can contain tabs, so a flyout entry expands into a tabbed section.
Q39.How do you store sensitive data locally in a .NET MAUI app, and what is the difference between Preferences and SecureStorage?
Preferences and SecureStorage?For sensitive data (tokens, credentials) use SecureStorage, which encrypts values using the platform keystore; Preferences is for small, non-sensitive settings stored in plain platform key-value storage.
SecureStorage:
Backed by the Android Keystore and iOS Keychain, so values are encrypted at rest.
Async API: SetAsync, GetAsync; store only strings, ideal for auth tokens.
Preferences:
Uses SharedPreferences (Android) / NSUserDefaults (iOS): NOT encrypted.
Good for simple settings (theme, flags, last tab) via Preferences.Set / Get.
Rule of thumb: Anything a user would be harmed by if leaked goes in SecureStorage; trivial preferences go in Preferences.
Q40.When using SQLite-net in a mobile app, why is it important to use the Async connection, and how do you handle database migrations on a user's device?
SQLite-net in a mobile app, why is it important to use the Async connection, and how do you handle database migrations on a user's device?Use the async connection (SQLiteAsyncConnection) so database work runs off the UI thread and keeps the app responsive; handle migrations yourself using CreateTableAsync and versioned schema updates because there's no automatic migration on-device.
Why async:
Disk I/O is slow; a synchronous query on the UI thread freezes the app and can trigger ANRs.
await on SQLiteAsyncConnection offloads the work to a background thread while keeping the UI fluid.
Migrations on device:
CreateTableAsync auto-adds new columns (additive changes) but won't drop/rename or transform data.
Track a schema version (e.g. in Preferences or PRAGMA user_version) and run incremental migration steps on upgrade.
For complex changes, execute raw SQL via ExecuteAsync to create new tables and copy data.
Practical tip: Always test migrations on an app that already has old data, not just a fresh install.
Q41.Compare Preferences, SecureStorage, and a local SQLite database — when is it appropriate to use each for persisting data on a mobile device?
Preferences, SecureStorage, and a local SQLite database — when is it appropriate to use each for persisting data on a mobile device?Choose based on data size and sensitivity: Preferences for small non-sensitive key-value settings, SecureStorage for small secrets that need encryption, and SQLite for structured, queryable, or large datasets.
Preferences:
Best for: user settings, flags, last-selected values.
Simple key-value, unencrypted, tiny primitives only.
SecureStorage:
Best for: auth tokens, passwords, API keys.
Encrypted via Keychain/Keystore, async, small string values, slower than Preferences.
SQLite database:
Best for: relational/structured data, lists, offline caches, anything you query or sort.
Supports large volumes and complex queries; more setup and not encrypted by default (use SQLCipher if needed).
Decision cue: Sensitive + small: SecureStorage; trivial + small: Preferences; large or structured: SQLite.
Q42.What are the best practices for using HttpClient in a mobile MAUI/Xamarin app, including reuse and native handlers?
HttpClient in a mobile MAUI/Xamarin app, including reuse and native handlers?Create HttpClient once and reuse it for the app's lifetime, configure a native platform handler for performance and TLS, and never wrap it in a using per request.
Reuse a single instance:
Creating a new HttpClient per call exhausts sockets (socket exhaustion / TIME_WAIT) and drops connection pooling.
Register it as a singleton via DI or use IHttpClientFactory (available in MAUI) to manage handler lifetimes.
Use native handlers:
MAUI defaults to native handlers (NSUrlSessionHandler on iOS, AndroidMessageHandler backed by OkHttp) for better performance, HTTP/2, and platform TLS.
You can override with SetupHandlerChain or pass a custom handler to configure certificate pinning, proxies, or timeouts.
Set sensible timeouts and cancellation: Mobile networks are flaky: set Timeout and pass a CancellationToken so requests abort cleanly on navigation.
Add resilience: Use Polly (via IHttpClientFactory) for retries with backoff and circuit breakers to survive transient failures.
Set default headers once: Configure base address and auth headers on the shared instance rather than per call.
Q43.What are "Value Converters," and in what scenario would you implement a multi-binding converter?
A value converter implements IValueConverter to transform a bound value between the source (ViewModel) and target (UI); a multi-binding converter implements IMultiValueConverter to combine several source values into one target value.
Single value converter: Convert() transforms source to UI (e.g. bool to Color), ConvertBack() reverses it for two-way bindings.
Multi-binding converter:
Used with MultiBinding when the output depends on more than one property.
Convert() receives an object[] of all bound values.
Typical multi-binding scenario: Enable a submit button only when several fields are valid, or format a full name from FirstName and LastName.
Q44.Explain the concept of 'Value Converters.' When would you use a converter versus logic inside a ViewModel property?
A value converter (IValueConverter) transforms a value purely for presentation as it flows between ViewModel and UI; use it for reusable, view-specific formatting, and use a ViewModel property when the logic is business state or needs testing/notification.
Use a converter when:
The transformation is purely visual (e.g. bool to visibility, enum to icon, number to color).
It's reusable across many views and doesn't belong in the model.
It avoids polluting the ViewModel with UI-only concerns.
Use a ViewModel property when:
The value is real state or business logic that should be unit tested.
It must raise INotifyPropertyChanged so the UI updates when inputs change.
Multiple views or commands depend on the computed value (expose it once).
Rule of thumb: Presentation formatting to converter; decisions and derived state to the ViewModel.
Q45.How does BindingContext propagate through the visual tree, and how does setting it on a page affect child controls?
BindingContext propagate through the visual tree, and how does setting it on a page affect child controls?BindingContext is inherited down the visual tree: a child that has no explicit BindingContext of its own automatically uses its parent's, so setting it on a page makes it the default context for every descendant.
Inheritance mechanism:
BindingContext is a bindable property that propagates through parent-child relationships automatically.
Set it once on the page (usually to the ViewModel) and all child bindings resolve against it.
Overriding on a child: Explicitly setting a child's BindingContext breaks inheritance for that element and its subtree (common for a CollectionView item bound to an item ViewModel).
DataTemplate scope:
Inside a DataTemplate, each generated cell's context is the individual item, not the page ViewModel.
To reach the parent context from within a template, use RelativeSource bindings (AncestorType).
Q46.Explain the performance implications of deeply nested layouts in MAUI and why a Grid is generally preferred over multiple nested StackLayouts.
Grid is generally preferred over multiple nested StackLayouts.Deeply nested layouts multiply the measure/arrange work the layout engine must do, and each nesting level re-measures its children, so an over-nested tree is slower to render and re-layout; a single Grid often replaces several nested StackLayouts with one flat pass.
Why nesting is costly:
Layout is recursive: each parent measures then arranges each child, so cost grows with depth and child count.
StackLayout can trigger extra measure passes (especially with */expand behavior), and nesting compounds it.
More views also means more memory and slower creation, which hurts scrolling in cells.
Why Grid is preferred:
A single Grid with rows and columns positions many children in one flat layout instead of a deep stack of containers.
Fewer visual elements means fewer measure/arrange cycles and a shallower tree.
Practical guidance:
Flatten layouts, prefer Grid for 2D arrangement, and keep DataTemplates simple for smooth scrolling.
Avoid nesting StackLayouts just to add margins/alignment that a Grid or spacing property handles.
Q47.What are "Visual States" and the "Visual State Manager" (VSM), and how do they help in creating responsive UIs?
Visual States are named collections of property setters that describe how a control should look in a particular condition (e.g. focused, disabled, or a wide-vs-narrow window), and the VisualStateManager applies them at runtime. Together they let you adapt UI declaratively without code-behind or triggers.
Visual State:
A named state (Normal, Focused, Disabled) holding Setter objects for one or more properties.
States are grouped in a VisualStateGroup; only one state per group is active at a time.
Visual State Manager: Switches states automatically for common ones (controls call GoToState on focus, press, etc.), or manually via VisualStateManager.GoToState(view, "StateName").
Why it helps responsive UI:
Adaptive layouts: use AdaptiveTrigger with a MinWindowWidth so states change based on window size.
Keeps look-and-feel in XAML and reusable through styles instead of scattered if logic.
Q48.How does .NET MAUI handle SVG files during the build process, and what happens to a single SVG asset when the app is compiled for various screen densities?
SVG files during the build process, and what happens to a single SVG asset when the app is compiled for various screen densities?In .NET MAUI you author a single SVG and the build converts it to a PNG at compile time; SVGs are not rendered live at runtime. Because SVGs are vector-based, the tooling can rasterize them at the resolutions each platform needs, so you ship one source asset instead of many bitmap variants.
Marked as MauiImage: Files under Resources/Images get build action MauiImage and are processed by the Resizetizer tooling.
Converted to PNG at build: The SVG is rasterized to PNG; you reference it in code/XAML by the .png name (e.g. logo.svg becomes logo.png).
Multiple densities generated:
Android gets mdpi/hdpi/xhdpi/etc., iOS gets @1x/@2x/@3x, Windows gets scale variants, all from the one vector source.
Use BaseSize on the MauiImage item to define the logical size before scaling.
Benefit: Crisp images on all screens with no manual export of size variants and a smaller, cleaner source tree.
Q49.Explain the difference between XAML Hot Reload and .NET (C#) Hot Reload, and what are the conceptual limitations of what can be updated while the app is running?
C#) Hot Reload, and what are the conceptual limitations of what can be updated while the app is running?XAML Hot Reload pushes UI markup changes to the running app without restarting, while .NET (C#) Hot Reload applies changes to your C# code (method bodies, logic) in the live process via the runtime's Edit and Continue support. They complement each other: one for the visual tree, one for behavior.
XAML Hot Reload:
Edits to XAML re-parse and update the visual tree live, preserving navigation and state.
Purely UI: layout, styles, bindings, added controls.
.NET (C#) Hot Reload:
Applies code edits to the loaded assemblies without a rebuild/redeploy.
Great for tweaking method logic, event handlers, and view-model code.
Conceptual limitations:
Structural/type changes are hard: adding fields, changing method signatures, altering class hierarchy, or new types often need a restart.
Code already executed won't re-run: changes to a constructor or OnAppearing won't retroactively apply until that code runs again.
XAML changes are applied but code-behind partial changes may require the C# path.
Q50.What is compiled XAML (XAMLC), and what advantages does it provide over interpreted XAML at runtime?
XAMLC), and what advantages does it provide over interpreted XAML at runtime?Compiled XAML (XAMLC) compiles your XAML into IL at build time instead of parsing the XML text at runtime. This makes apps start faster, catches XAML errors during the build, and reduces assembly size by stripping the embedded XAML.
How it works:
The XAML is turned into compiled code during build; without it, the runtime reads and interprets the XAML string when the page loads.
Enabled by default in MAUI; controlled with [XamlCompilation(XamlCompilationOptions.Compile)].
Advantages:
Faster load: no runtime XML parsing per page.
Compile-time validation: mistyped elements or properties fail the build, not the user.
Smaller footprint: the XAML file no longer needs to be embedded as a resource.
Caveat: Some highly dynamic runtime XAML scenarios (loading XAML from a string) still rely on interpretation.
Q51.What are the tradeoffs of building your UI in XAML versus building it entirely in C#?
C#?XAML gives you a declarative, designer-friendly separation of UI from logic with tooling like Hot Reload, while pure C# UI gives you full compile-time safety, easier dynamic construction, and no XML parsing. The right choice depends on team preference, how dynamic the UI is, and tooling needs.
XAML strengths:
Declarative and readable for static layouts; clean separation from code-behind.
Rich binding syntax, styles, resources, and XAML Hot Reload support.
XAML weaknesses: Errors can surface at runtime (mitigated by XAMLC), and complex conditional/loop-driven UI is awkward.
C# UI strengths:
Full compile-time checking, refactoring, and IntelliSense on the whole UI.
Natural for dynamic, data-driven UI (loops, conditionals); libraries like C# Markup or Comet make it terse.
C# UI weaknesses: More verbose for static layouts and less designer/preview tooling.
Practical note: Both compile to the same visual tree; you can even mix them, using XAML for structure and C# for dynamic pieces.
Q52.What are markup extensions in XAML, and what are some built-in ones you commonly use?
Markup extensions are a XAML syntax (values inside curly braces) that produce a value for a property at load time by running code, rather than a literal string. They enable references, bindings, and resource lookups that a plain attribute value could not express.
How they look: Written as {ExtensionName arg}; they implement IMarkupExtension and return the resolved value.
Common built-ins:
Binding: binds a property to a source/view-model member.
StaticResource / DynamicResource: pull values from ResourceDictionary (dynamic re-resolves on change).
x:Static: reference a static field/property/constant.
x:Reference: reference another named element in the XAML.
OnPlatform / OnIdiom: platform/device-specific values.
Custom: You can write your own by implementing IMarkupExtension<T> and its ProvideValue method.
Q53.What are the common causes of slow app startup in a MAUI/Xamarin application?
Slow startup is usually a mix of too much eager work before the first frame, JIT/assembly-loading overhead, and a heavy initial visual tree, all executed on the UI thread.
Heavy application initialization:
Registering and eagerly instantiating many DI services in MauiProgram.CreateMauiApp().
Synchronous I/O, database migrations, or network calls during launch.
Runtime code costs:
JIT compilation on Android when AOT/startup tracing is disabled.
Runtime XAML parsing when XamlC is off, and reflection-heavy serialization.
Large or complex UI: Deeply nested layouts, big resource dictionaries, and loading full data before showing anything.
App size effects: Many/large assemblies increase load time; trimming and reducing dependencies helps.
Q54.What is "Trimming" (Linker) and why is it critical for mobile app distribution?
Trimming (via ILLink) statically removes unused IL and whole assemblies from the published app, dramatically shrinking the binary and reducing memory/load time, which matters because mobile apps have strict size limits and constrained devices.
What it is:
A link-time step that walks the reachable call graph and discards everything not referenced.
Controlled by TrimMode (e.g. partial vs full) and PublishTrimmed.
Why it's critical for distribution:
App store size limits and cellular download caps make smaller packages essential.
Less code to load means faster startup and lower memory use.
On iOS it pairs with AOT: less code to AOT-compile means smaller native binaries.
The catch: It cannot see reflection-only usage, so you must annotate/preserve those types or use trim-safe patterns to avoid Release-only crashes.
Q55.How do you handle Dark Mode and Light Mode natively within the MAUI framework?
MAUI supports theming natively through AppThemeBinding, which picks a value based on the current system theme, plus Application.Current.RequestedTheme to read it and UserAppTheme to override it.
AppThemeBinding in XAML:
Provides Light and Dark values inline: MAUI swaps automatically when the OS theme changes.
Works great with resource dictionaries so colors are defined once and reused.
Reading and forcing a theme:
Read with Application.Current.RequestedTheme (returns AppTheme.Light/Dark/Unspecified).
Force a theme regardless of OS by setting Application.Current.UserAppTheme.
React to changes at runtime: Subscribe to Application.Current.RequestedThemeChanged to update logic-driven styling.
Q56.How does .NET MAUI handle accessibility (A11y)? What are "Semantic Properties"?
MAUI maps its accessibility API onto each platform's native accessibility services (TalkBack, VoiceOver, Narrator). SemanticProperties are attached properties that tell screen readers what an element is, describes, or hints, without changing its visual appearance.
SemanticProperties.Description: A label a screen reader announces (e.g. an icon-only button gets "Save").
SemanticProperties.Hint: Extra guidance on what happens when the element is activated.
SemanticProperties.HeadingLevel: Marks a control as a heading so users can navigate by structure.
Programmatic focus and announcements: Use SemanticScreenReader.Announce() to speak a message and control.SetSemanticFocus() to move reader focus.
Why it matters: It is cross-platform: one property set drives each OS's native a11y engine, keeping apps compliant and usable.
Q57.How does .NET MAUI handle permissions across different platforms?
MAUI centralizes permission requests through the Permissions API in Essentials: you check and request a strongly-typed permission from shared code, and MAUI maps it to each platform's native permission model and prompt.
Unified API: Permissions.CheckStatusAsync<T>() and Permissions.RequestAsync<T>() work against types like Permissions.LocationWhenInUse.
Platform declarations still required: You must declare permissions natively: Android AndroidManifest.xml, iOS Info.plist usage strings, Windows Package.appxmanifest.
Platform behavior differs: iOS prompts once (then you route users to Settings); Android prompts at runtime and may need rationale handling.
Custom permissions: Subclass Permissions.BasePermission for anything not built in.
Q58.What is GraphicsView and how do you use Microsoft.Maui.Graphics to draw custom visuals?
GraphicsView and how do you use Microsoft.Maui.Graphics to draw custom visuals?GraphicsView is a MAUI control that gives you a cross-platform drawing surface: you assign it an IDrawable whose Draw() method receives an ICanvas and a RectF, and you issue commands via the Microsoft.Maui.Graphics API to render shapes, text, and images with native backends.
The building blocks:
GraphicsView hosts the surface and exposes a Drawable property.
You implement IDrawable and put your rendering logic in void Draw(ICanvas canvas, RectF dirtyRect).
ICanvas is the drawing context: set state (StrokeColor, FillColor, StrokeSize, FontSize), then call operations (DrawLine, DrawRectangle, FillEllipse, DrawString, DrawPath).
How it renders:
Each platform provides a concrete ICanvas backed by the native graphics engine (Core Graphics on iOS, Android canvas, Win2D/SkiaSharp on Windows), so one drawing code path works everywhere.
The dirtyRect gives the region being drawn, useful for scaling content to the view size.
Triggering a redraw: Draw() is not called continuously: invoke graphicsView.Invalidate() whenever your data changes to request a repaint.
When to use it:
Custom charts, gauges, signatures, sparklines, or any visual not expressible with standard controls or Shapes.
For very high-performance or complex scenes, prefer SkiaSharp directly.
Q59.Why did Microsoft replace the Renderer architecture with Handlers, and what were the performance and decoupling issues with the old model?
Microsoft replaced Renderers with Handlers because Renderers were tightly coupled, heavy, and hard to extend or customize without subclassing: Handlers decouple the cross-platform control from its native view through a thin mapper, making them lighter and easier to tweak.
Tight coupling in Renderers: Each Xamarin.Forms control referenced its Renderer and vice versa, so the abstraction knew about the native layer and was hard to test or swap.
Performance overhead: Renderers were relatively heavyweight objects and relied on chatty property propagation; the mapper-based Handler pattern reduces object cost and indirection.
Customization was painful: Changing one property meant writing a full custom Renderer subclass; Handlers let you modify behavior globally via the Mapper without subclassing.
Decoupling via interfaces: Controls implement interfaces (e.g. IButton) that Handlers target, so the virtual view and native view stay independent and independently testable.
Q60.What is the fundamental difference between the 'Renderer' architecture in Xamarin.Forms and the 'Handler' architecture in .NET MAUI?
Xamarin.Forms and the 'Handler' architecture in .NET MAUI?Q61.What runtime does MAUI use on iOS versus Android (Mono, interpreter mode), and how does that affect app behavior?
Mono, interpreter mode), and how does that affect app behavior?Q62.How do you perform automated UI testing for a MAUI/Xamarin app using Appium or Xamarin.UITest?
Appium or Xamarin.UITest?Q63.What is the Window class in .NET MAUI, and how does it enable multi-window support on desktop platforms?
Window class in .NET MAUI, and how does it enable multi-window support on desktop platforms?Q64.What is the migration path for a legacy Xamarin.Forms app to .NET MAUI, including the role of the Upgrade Assistant, namespace changes, and refactoring custom renderers?
Q65.What is the Compatibility Shim in .NET MAUI, and when and why would you use it during a migration from Xamarin.Forms?
Xamarin.Forms?Q66.What are Effects in Xamarin.Forms, and how do they compare to custom renderers or MAUI handlers for tweaking native controls?
Q67.How do you consume a native platform library from MAUI/Xamarin using a binding library, and what challenges does that involve?
Q68.What is the MessagingCenter or WeakReferenceMessenger? When should you use it, and what are the risks regarding memory leaks?
MessagingCenter or WeakReferenceMessenger? When should you use it, and what are the risks regarding memory leaks?Q69.How does URI-based routing work in Shell, and how would you navigate to a deep-linked page and pass complex data using Query Parameters?
Q70.How would you handle Offline-First data synchronization in a MAUI app between a local SQLite database and a remote API?
SQLite database and a remote API?Q71.Explain Compiled Bindings (x:DataType). How do they improve performance and catch errors compared to standard reflection-based bindings?
x:DataType). How do they improve performance and catch errors compared to standard reflection-based bindings?Q72.Why is Ahead-of-Time (AOT) compilation mandatory for iOS, and how does it differ from the JIT compilation used on Android?
JIT compilation used on Android?Q73.What is the 'Linker' (or Trimmer), and why is it common for a MAUI app to work in Debug but crash in Release mode?
Debug but crash in Release mode?Q74.What are some common strategies to improve the "Time to Main Window" (startup time) in a heavy MAUI application?
Q75.What are the common causes of memory leaks in .NET MAUI, specifically regarding event handlers and circular references in UI controls?
Q76.What is NativeAOT in the context of .NET 8/9 mobile apps, and how does it differ from the standard Mono AOT?
NativeAOT in the context of .NET 8/9 mobile apps, and how does it differ from the standard Mono AOT?Q77.What is "Blazor Hybrid," and what are the trade-offs of using BlazorWebView inside a MAUI app versus using pure XAML?
BlazorWebView inside a MAUI app versus using pure XAML?Q78.How does the BlazorWebView communicate with the native MAUI container?
BlazorWebView communicate with the native MAUI container?Q79.What is a "Handler Mapper," and how would you use it to modify a native property of a built-in control?
Q80.How does .NET MAUI handle drawing (Microsoft.Maui.Graphics) for elements like Shapes and Shadows compared to the platform-specific drawing used in Xamarin?
Microsoft.Maui.Graphics) for elements like Shapes and Shadows compared to the platform-specific drawing used in Xamarin?