{"id":2166,"date":"2025-06-26T19:16:10","date_gmt":"2025-06-26T19:16:10","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/06\/26\/simpler-xaml-in-net-maui-10\/"},"modified":"2025-06-26T19:16:10","modified_gmt":"2025-06-26T19:16:10","slug":"simpler-xaml-in-net-maui-10","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2025\/06\/26\/simpler-xaml-in-net-maui-10\/","title":{"rendered":"Simpler XAML in .NET MAUI 10"},"content":{"rendered":"<p>Building UI in .NET MAUI with XAML continues to be the most popular approach. It\u2019s easy to see the nesting structure of your UI, works for most use cases with hot reload, and it supports powerful state flow with data binding. One of the downsides is how verbose it can become. Every page requires you to declare the namespaces for any types used, provide prefixes for them, and of course use them. You\u2019re likely a better developer than I am, but I very often use a different prefix for the same namespace in different files making quite a mess.<\/p>\n<p>.NET 6 introduced global and implicit usings for C# which greatly reduced the using statements at the head of many C# files. Now in .NET 10 starting with Preview 5 we are introducing the same for XAML so you can declare your namespaces and prefixes in a single file and use them throughout. In fact, you can now omit the use of prefixes altogether!<\/p>\n<h2>Implicit Namespaces<\/h2>\n<p>This update begins by switching the global namespace that all XAML files used in .NET MAUI from xmlns=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui&#8221; to xmlns=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;. Now there is a truly global namespace unique to your application where we can pack other namespaces for use throughout the codebase.<\/p>\n<p>Opt-in to the implicit namespaces by adding this configuration to your project file.<\/p>\n<p>&lt;PropertyGroup&gt;<br \/>\n    &lt;DefineConstants&gt;$(DefineConstants);MauiAllowImplicitXmlnsDeclaration&lt;\/DefineConstants&gt;<br \/>\n    &lt;EnablePreviewFeatures&gt;true&lt;\/EnablePreviewFeatures&gt;<br \/>\n&lt;\/PropertyGroup&gt;<\/p>\n<p>Now your project will implicitly include these 2 namespaces which you\u2019ve been accustomed to seeing in every XAML file since .NET MAUI first shipped.<\/p>\n<p>xmlns=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui&#8221;<br \/>\nxmlns:x=&#8221;http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml&#8221;<\/p>\n<p>Because x: is used by the XAML inflator, you still need to use that prefix. With this change alone, your XAML for a view gets much tighter.<\/p>\n<h3>Before<\/h3>\n<p>&lt;ContentPage<br \/>\n    xmlns=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui&#8221;<br \/>\n    xmlns:x=&#8221;http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml&#8221;<br \/>\n    x:Class=&#8221;MyApp.Pages.MyContentPage&#8221;&gt;<br \/>\n&lt;\/ContentPage&gt;<\/p>\n<h3>After<\/h3>\n<p>&lt;ContentPage x:Class=&#8221;MyApp.Pages.MyContentPage&#8221;&gt;<br \/>\n&lt;\/ContentPage&gt;<\/p>\n<h2>Global Namespaces<\/h2>\n<p>As you start to include classes of your own and from any of the many useful NuGet packages for .NET MAUI, the stack of xmlns in your XAML starts to grow like a layer cake. This is the MainPage from my app <a href=\"https:\/\/github.com\/davidortinau\/telepathy\">Telepathy<\/a><\/p>\n<p>&lt;ContentPage xmlns=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/2021\/maui&#8221;<br \/>\n             xmlns:x=&#8221;http:\/\/schemas.microsoft.com\/winfx\/2009\/xaml&#8221;<br \/>\n             xmlns:pageModels=&#8221;clr-namespace:Telepathic.PageModels&#8221;<br \/>\n             xmlns:viewModels=&#8221;clr-namespace:Telepathic.ViewModels&#8221;<br \/>\n             xmlns:models=&#8221;clr-namespace:Telepathic.Models&#8221;<br \/>\n             xmlns:converters=&#8221;clr-namespace:Telepathic.Converters&#8221;<br \/>\n             xmlns:controls=&#8221;clr-namespace:Telepathic.Pages.Controls&#8221;<br \/>\n             xmlns:sf=&#8221;clr-namespace:Syncfusion.Maui.Toolkit.TextInputLayout;assembly=Syncfusion.Maui.Toolkit&#8221;<br \/>\n             xmlns:cards=&#8221;clr-namespace:Syncfusion.Maui.Toolkit.Cards;assembly=Syncfusion.Maui.Toolkit&#8221;<br \/>\n             xmlns:b=&#8221;clr-namespace:Syncfusion.Maui.Toolkit.Buttons;assembly=Syncfusion.Maui.Toolkit&#8221;<br \/>\n             xmlns:pullToRefresh=&#8221;clr-namespace:Syncfusion.Maui.Toolkit.PullToRefresh;assembly=Syncfusion.Maui.Toolkit&#8221;<br \/>\n             xmlns:bottomSheet=&#8221;clr-namespace:Syncfusion.Maui.Toolkit.BottomSheet;assembly=Syncfusion.Maui.Toolkit&#8221;<br \/>\n             xmlns:toolkit=&#8221;http:\/\/schemas.microsoft.com\/dotnet\/2022\/maui\/toolkit&#8221;<br \/>\n             xmlns:aloha=&#8221;clr-namespace:AlohaKit.Animations;assembly=AlohaKit.Animations&#8221;<br \/>\n             xmlns:effectsView=&#8221;http:\/\/schemas.syncfusion.com\/maui\/toolkit&#8221;<br \/>\n             x:Class=&#8221;Telepathic.Pages.MainPage&#8221;<br \/>\n             x:DataType=&#8221;pageModels:MainPageModel&#8221;<br \/>\n             Title=&#8221;{Binding Today}&#8221;&gt;<br \/>\n&lt;\/ContentPage&gt;<\/p>\n<p>Yikes! Many of my XAML files use the same namespaces over and over such as pageModels, models, converters, controls, and so on. To globalize these, I created a GlobalXmlns.cs file where I can register these namespaces using XmlnsDefinition.<\/p>\n<p>[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Telepathic.PageModels&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Telepathic.Models&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Telepathic.Converters&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Telepathic.Pages.Controls&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Telepathic.ViewModels&#8221;)]<\/p>\n<p>I can also use the same to globalize third-party controls like the <a href=\"https:\/\/github.com\/syncfusion\/maui-toolkit\">Syncfusion Toolkit for .NET MAUI<\/a>, the <a href=\"https:\/\/github.com\/CommunityToolkit\/Maui\">Community Toolkit for .NET MAUI<\/a>, and <a href=\"https:\/\/github.com\/jsuarezruiz\/AlohaKit.Animations\">AlohaKit Animations<\/a> used in this file.<\/p>\n<p>[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Syncfusion.Maui.Toolkit.TextInputLayout&#8221;, AssemblyName = &#8220;Syncfusion.Maui.Toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Syncfusion.Maui.Toolkit.Cards&#8221;, AssemblyName = &#8220;Syncfusion.Maui.Toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Syncfusion.Maui.Toolkit.Buttons&#8221;, AssemblyName = &#8220;Syncfusion.Maui.Toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Syncfusion.Maui.Toolkit.PullToRefresh&#8221;, AssemblyName = &#8220;Syncfusion.Maui.Toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;Syncfusion.Maui.Toolkit.BottomSheet&#8221;, AssemblyName = &#8220;Syncfusion.Maui.Toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;http:\/\/schemas.syncfusion.com\/maui\/toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/2022\/maui\/toolkit&#8221;)]<br \/>\n[assembly: XmlnsDefinition(<br \/>\n    &#8220;http:\/\/schemas.microsoft.com\/dotnet\/maui\/global&#8221;,<br \/>\n    &#8220;AlohaKit.Animations&#8221;, AssemblyName = &#8220;AlohaKit.Animations&#8221;)]<\/p>\n<p>After this I can remove all those declarations from the head of the file, resulting in a much cleaner read.<\/p>\n<p>&lt;ContentPage x:Class=&#8221;Telepathic.Pages.MainPage&#8221;<br \/>\n             x:DataType=&#8221;MainPageModel&#8221;<br \/>\n             Title=&#8221;{Binding Today}&#8221;&gt;<br \/>\n&lt;\/ContentPage&gt;<\/p>\n<h2>Namespace Prefixes<\/h2>\n<p>Now that the xmlns are all gone, you may be wondering about the prefixes that had been defined in order to reference those controls in XAML. Well, you no longer need them! Notice in the previous example the x:DataType omits the pageModels: prefix previously required.<\/p>\n<p>Let\u2019s look at another example from this same page.<\/p>\n<p>&lt;BindableLayout.ItemTemplate&gt;<br \/>\n    &lt;DataTemplate x:DataType=&#8221;models:ProjectTask&#8221;&gt;<br \/>\n        &lt;controls:TaskView<br \/>\n            TaskCompletedCommand=&#8221;{Binding CompletedCommand,<br \/>\n                                    Source={RelativeSource AncestorType={x:Type pageModels:MainPageModel}},<br \/>\n                                    x:DataType=pageModels:MainPageModel}&#8221;\/&gt;<br \/>\n    &lt;\/DataTemplate&gt;<br \/>\n&lt;\/BindableLayout.ItemTemplate&gt;<\/p>\n<p>After<\/p>\n<p>&lt;BindableLayout.ItemTemplate&gt;<br \/>\n    &lt;DataTemplate x:DataType=&#8221;ProjectTask&#8221;&gt;<br \/>\n        &lt;TaskView<br \/>\n            TaskCompletedCommand=&#8221;{Binding CompletedCommand,<br \/>\n                                    Source={RelativeSource AncestorType={x:Type MainPageModel}},<br \/>\n                                    x:DataType=MainPageModel}&#8221;\/&gt;<br \/>\n    &lt;\/DataTemplate&gt;<br \/>\n&lt;\/BindableLayout.ItemTemplate&gt;<\/p>\n<h2>Disambiguating Types<\/h2>\n<p>There will be times when you have types that collide and you\u2019ll need to disambiguate them. I ran into this in another application where I have a custom control called FlyoutItem in my namespace ControlGallery.Views. In the XAML file it was being reference like &lt;views:FlyoutItem \/&gt; and all was well. When I added ControlGallery.Views to the global namespace and removed the views: prefix, I encountered a collision because .NET MAUI already has a type FlyoutItem!<\/p>\n<p>One way I could solve this would be to use the full path with namespace in the XAML like &lt;ControlGallery.Views.FlyoutItem \/&gt;. That is pretty long and not my preference.<\/p>\n<p>Instead, there\u2019s another attribute I can use alongside XmlnsDefinition and that\u2019s XmlnsPrefix. Back in the GlobalXmlns.cs I can add a prefix for this namespace that\u2019ll be usable globally in my application.<\/p>\n<p>[assembly: XmlnsPrefix(<br \/>\n    &#8220;clr-namespace:ControlGallery.Views&#8221;,<br \/>\n    &#8220;views&#8221;)]<\/p>\n<p>Now once again in XAML I can use that prefix like &lt;views:FlyoutItem \/&gt;.<\/p>\n\n<div class=\"alert alert-primary\">\n<p class=\"alert-divider\"><strong>Note<\/strong><\/p>\n<p>Before you go all in on this, be aware it\u2019s a preview and there are issues to be ironed out. For example, the XAML Language Service needs some love to make it aware of what\u2019s happening so you don\u2019t get red squiggles everywhere. Additionally, work needs to be done to address the negative startup and runtime performance impact.<\/p><\/div>\n<h2>Resources<\/h2>\n<p><a href=\"https:\/\/learn.microsoft.com\/dotnet\/maui\/whats-new\/dotnet-10#xaml-with-implicit--global-xml-namespaces-preview-5\">What\u2019s New in .NET MAUI for .NET 10<\/a><br \/>\n<a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet\/10.0\">Download .NET 10 Preview<\/a><br \/>\n<a href=\"https:\/\/learn.microsoft.com\/dotnet\/maui\/xaml\/namespaces\/?view=net-maui-9.0\">.NET MAUI XAML Namespaces Documentation<\/a><\/p>\n<h2>Known Issues<\/h2>\n<p>Debug builds are currently slower to startup<br \/>\nRuntime view inflation is slower<br \/>\nXAML editors incorrectly report unknown types via red squiggles (e.g. XLS0414)<br \/>\nDeclaring prefixes for namespaces in the project requires including clr-namespace:<\/p>\n<h2>Feedback<\/h2>\n<p>You can get started by installing .NET 10 Preview 5 with the .NET MAUI workload or Visual Studio 17.14 Preview, and then creating a new project.<\/p>\n<p>dotnet new maui -n LessXamlPlease<\/p>\n<p>We need your feedback! Give this a go and let us know what you think by <a href=\"https:\/\/github.com\/dotnet\/maui\/issues\">opening an issue on GitHub<\/a> or sending me a note directly at <a href=\"mailto:david.ortinau@microsoft.com\">david.ortinau@microsoft.com<\/a>.<\/p>\n<p>The post <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\/simpler-xaml-in-dotnet-maui-10\/\">Simpler XAML in .NET MAUI 10<\/a> appeared first on <a href=\"https:\/\/devblogs.microsoft.com\/dotnet\">.NET Blog<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Building UI in .NET MAUI with XAML continues to be the most popular approach. It\u2019s easy to see the nesting [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[7],"tags":[],"class_list":["post-2166","post","type-post","status-publish","format-standard","hentry","category-dotnet"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=2166"}],"version-history":[{"count":0,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/2166\/revisions"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=2166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=2166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=2166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}