Every major .NET release brings MAUI improvements, but .NET 10 stands out. The team didn’t just add features — they made architectural decisions that will shape how MAUI apps are built for the next several years. CollectionView replacing ListView as the default, .NET Aspire integration for backend connectivity, and a rebuilt MediaPicker are the headline changes. But there’s more under the hood.
This post covers every significant change in .NET MAUI 10, with code examples and upgrade guidance for existing apps.
Table of Contents
- CollectionView Is Now the Default List Control
- ListView Officially Deprecated
- NET Aspire Integration
- MediaPicker Overhaul
- Performance Improvements
- Shell Navigation Updates
- Handler Improvements
- Breaking Changes and Migration Notes
- FAQ
- Conclusion
CollectionView Is Now the Default List Control
The most impactful change in .NET 10 MAUI: CollectionView is now the recommended default for all list scenarios. New project templates use CollectionView exclusively, and the MAUI documentation has been updated to reflect this as the primary control.
Why CollectionView Wins
- Virtualization by default — only renders items visible on screen, handles 10,000+ items without frame drops
- Flexible layouts — vertical/horizontal list, grid, or custom layout via
ItemsLayout - No ViewCell requirement — data templates directly contain your UI without the overhead of
ViewCell - Selection modes — None, Single, Multiple out of the box
- Empty view — native support for displaying content when the collection is empty
<CollectionView ItemsSource="{Binding Products}"
SelectionMode="Single"
SelectedItem="{Binding SelectedProduct}">
<CollectionView.EmptyView>
<Label Text="No products found."
HorizontalOptions="Center"
VerticalOptions="Center" />
</CollectionView.EmptyView>
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="model:Product">
<Frame Margin="4" CornerRadius="8" Padding="12">
<VerticalStackLayout>
<Label Text="{Binding Name}" FontAttributes="Bold" />
<Label Text="{Binding Price, StringFormat='${0:F2}'}"
TextColor="#6200EE" />
</VerticalStackLayout>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
New in .NET 10: CollectionView Scroll Anchoring
.NET 10 adds scroll anchoring — the scroll position is preserved when items are prepended to the collection (e.g., loading newer messages in a chat). Previously this required manual scroll position management:
<CollectionView ItemsSource="{Binding Messages}"
ItemsUpdatingScrollMode="KeepLastItemInView" />
ListView Officially Deprecated
ListView is marked deprecated in .NET 10 and will be removed in a future release. It still works, but you’ll see deprecation warnings in the IDE and build output. The MAUI team recommends migrating all ListView usages to CollectionView.
Quick Migration Reference
<!-- ListView (deprecated) -->
<ListView ItemsSource="{Binding Items}"
HasUnevenRows="True"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding Name}" Padding="12" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<!-- CollectionView (replacement) -->
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Label Text="{Binding Name}" Padding="12" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Note: Remove ViewCell wrappers — CollectionView doesn’t need them and they add unnecessary overhead. [INTERNAL_LINK: Migrating from ListView to CollectionView complete guide]
.NET Aspire Integration
.NET Aspire — Microsoft’s opinionated stack for cloud-native applications — now has first-class support for MAUI projects. You can add your MAUI app to an Aspire AppHost alongside your backend APIs, databases, and services.
What Aspire Gives MAUI Developers
- Service discovery — MAUI app automatically resolves backend service URLs from Aspire’s service registry during development
- Dashboard integration — see MAUI app telemetry (traces, logs, metrics) in the Aspire developer dashboard alongside backend services
- Resilience defaults — Aspire configures retry policies and circuit breakers for HttpClient automatically
- Secrets management — development secrets flow from Aspire’s configuration into the MAUI app without manual env var management
// AppHost project — Program.cs
var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddProject<Projects.MyApp_Api>("api");
// Add MAUI app to Aspire host
builder.AddMauiProject<Projects.MyApp_Maui>("mauiapp")
.WithReference(api);
builder.Build().Run();
// In MauiProgram.cs — use Aspire service discovery
builder.Services.AddHttpClient<IProductService, ProductService>(client =>
{
// Resolves to the actual URL from Aspire's registry
client.BaseAddress = new Uri("https+http://api");
});
builder.AddServiceDefaults(); // Aspire defaults: health checks, telemetry, resilience
Development Workflow Improvement
Previously, running a MAUI app against a local API meant hardcoding localhost:5000 or managing launch profiles manually. With Aspire, the entire stack launches with one command and URLs resolve automatically.
MediaPicker Overhaul
The MediaPicker API in .NET 10 MAUI receives significant improvements addressing long-standing developer pain points.
Multiple File Selection
.NET 10 adds proper multiple media selection — previously you had to call PickPhotoAsync() once per image:
// .NET 10 — pick multiple photos at once
var results = await MediaPicker.PickMultiplePhotosAsync(new MediaPickerOptions
{
Title = "Select up to 10 photos",
MaximumCount = 10
});
if (results != null)
{
foreach (var photo in results)
{
var stream = await photo.OpenReadAsync();
// Process each photo
}
}
Video Capture Options
// New capture options in .NET 10
var video = await MediaPicker.CaptureVideoAsync(new VideoCaptureOptions
{
MaxDuration = TimeSpan.FromMinutes(5),
Quality = VideoQuality.Medium,
CameraDevice = CameraDevice.Rear
});
Image Compression
Built-in compression support — no more pulling in third-party image processing libraries for basic resize/compress:
var photo = await MediaPicker.PickPhotoAsync(new MediaPickerOptions
{
CompressionQuality = 0.8f, // 80% quality
MaxWidth = 1920,
MaxHeight = 1080
});
Performance Improvements
Startup Time Reduction
.NET 10 delivers measurable cold-start improvements across all MAUI platforms. The MAUI team reports approximately 15–20% faster cold start on Android through ahead-of-time (AOT) compilation improvements and reduced startup work in the handler initialization pipeline.
Memory Usage in Lists
CollectionView’s virtualization engine was rewritten for .NET 10 to reduce memory allocation per cell. Apps displaying large lists with images will see noticeable reduction in peak memory usage — particularly relevant on older Android devices with limited RAM.
Reduced App Binary Size
Improved linker analysis in .NET 10 trims unused MAUI framework code more aggressively. Typical MAUI app binary sizes reduced by 5–12% depending on which framework features are used.
<!-- Enable aggressive trimming in .csproj -->
<PropertyGroup>
<TrimMode>full</TrimMode>
<PublishTrimmed>true</PublishTrimmed>
<PublishAot>true</PublishAot> <!-- Android AOT -->
</PropertyGroup>
Shell Navigation Updates
Tab Bar Customization
.NET 10 expands Shell’s tab bar customization API — previously you needed platform-specific handler modifications for basic customizations like tab icon size or indicator colors:
<Shell TabBarBackgroundColor="#FFFFFF"
TabBarForegroundColor="#6200EE"
TabBarTitleColor="#6200EE"
TabBarUnselectedColor="#9E9E9E"
TabBarItemIconSize="24">
</Shell>
Route Guards
Navigation guards are now built into Shell — intercept navigation events to handle authentication, unsaved changes, or conditional routing:
public class AuthGuard : ShellNavigationGuard
{
private readonly IAuthService _auth;
public AuthGuard(IAuthService auth) => _auth = auth;
public override async Task<bool> CanNavigateAsync(ShellNavigatingEventArgs args)
{
if (args.Target.Location.OriginalString.Contains("dashboard"))
return await _auth.IsAuthenticatedAsync();
return true;
}
}
// Register in MauiProgram.cs
builder.Services.AddSingleton<ShellNavigationGuard, AuthGuard>();
Handler Improvements
Platform View Access Simplified
Accessing the underlying native view from a handler is cleaner in .NET 10:
// Before .NET 10
var nativeView = (handler as EntryHandler)?.PlatformView as UITextField;
// .NET 10
if (entry.Handler is EntryHandler entryHandler)
{
entryHandler.PlatformView.BackgroundColor = UIColor.Clear;
}
Mapper Chaining
Handler mapper modifications now support explicit ordering, preventing conflicts between multiple libraries that customize the same control:
EntryHandler.Mapper.PrependToMapping(nameof(Entry.Text), (handler, view) =>
{
// Runs before all other Text mappings
});
EntryHandler.Mapper.AppendToMapping("CustomStyling", (handler, view) =>
{
// Runs after all standard mappings
});
Breaking Changes and Migration Notes
- ListView — shows deprecation warnings; migrate to CollectionView before .NET 11
- Device.RuntimePlatform — fully removed (was deprecated in .NET 8); use
DeviceInfo.Platform - AbsoluteLayout absolute positioning syntax — updated to use
AbsoluteLayout.LayoutFlagsenum directly; old attached property syntax throws warnings - Frame control — deprecated in favor of
Border; Frame still works but migration is recommended - Minimum iOS version — raised to iOS 15 in .NET 10
- Minimum Android API — raised to API 24 (Android 7.0)
<!-- Frame (deprecated) -->
<Frame CornerRadius="12" BorderColor="#E0E0E0">
<Label Text="Content" />
</Frame>
<!-- Border (replacement) -->
<Border StrokeShape="RoundRectangle 12"
Stroke="#E0E0E0">
<Label Text="Content" />
</Border>
FAQ
Do I need to update my entire app to use .NET 10 features?
No — update the target framework in your .csproj to net10.0-android, etc., and you get access to all new features. You can migrate controls and APIs incrementally.
Is CollectionView faster than ListView for all scenarios?
For large lists: yes, significantly. For very small lists (under 10 items), the performance difference is negligible. The API improvements alone (no ViewCell, EmptyView, multiple layouts) justify using CollectionView even for short lists.
Does .NET Aspire work on physical iOS/Android devices?
Aspire service discovery uses local network addresses — physical devices on the same network can reach local Aspire-hosted services. Configure the MAUI app to use the machine’s local IP when running on a physical device.
When will ListView be fully removed?
The MAUI team has not announced a specific removal version, but the deprecation timeline typically spans two major versions. Expect removal around .NET 12. Migrate now to avoid a forced migration under deadline pressure.
Are there MAUI-specific NativeAOT improvements in .NET 10?
Yes — NativeAOT support for MAUI on iOS is improved in .NET 10, with better trimming analysis for MAUI-specific reflection patterns. Full NativeAOT for Android is still in progress but preview support is available.
Conclusion
.NET 10 is a maturity release for MAUI — the APIs are more complete, performance is measurably better, and the deprecation of ListView signals that the framework is willing to make hard calls to improve long-term quality. The Aspire integration is especially significant for teams building MAUI apps against cloud backends.
Upgrade path: update your target frameworks, fix deprecation warnings for ListView and Frame, and adopt the new MediaPicker APIs where you have media workflows. Most apps can be on .NET 10 within a sprint.
[INTERNAL_LINK: Migrating from ListView to CollectionView in .NET MAUI] [INTERNAL_LINK: .NET MAUI Shell navigation complete guide]

Leave a Reply