MAUI是基于MVVM模式的UI开发,是WPF的跨平台实现,基本可以无缝把项目转到MAUI里。
配置非常简单,如下图。

因为此教程是基于《WPF编程宝典C#2012 第4版》实现的,所以为了方便书中各种demo的显示,请大家按照以下步骤添加公用代码。
1. 项目建立三个项目,其中MauiViews是.NET MAUI应用,其余MauiModels和MauiViewModels是.NET MAUI类库。如下图。

记得通过依赖项,添加MauiModels和MauiViewModel为共享项目。我的Shares项目,是用来写其他平台相关的Core代码,为之后的项目做的准备。

2. 编译syncfusion第三方库为nupkg,因为我们会用到这个库的SfTabView和SfCartesianChart等,其他常用控件我们用微软自带的就行。为了方便之后省略命名空间,不用手动添加声明,所以修改源代码中的AssemblyInfo.cs如下(把这个库添加到系统默认的命名空间里了)。我要特别声明下,此库只能用于非商业目的,否则需要购买商业授权,请各位一定要熟知开源规则,以免造成不必要的罚款,开源地址https://github.com/syncfusion/maui-toolkit。官方教程地址https://help.syncfusion.com/maui/button/getting-started
using System.Runtime.CompilerServices;
using System.Resources;
[assembly: NeutralResourcesLanguage("zh-CN")]
[assembly: InternalsVisibleTo("Syncfusion.Maui.Toolkit.UnitTest")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Accordion")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.BottomSheet")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Buttons")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Calendar")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Cards")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Carousel")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Charts")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Chips")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.EffectsView")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Expander")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.NavigationDrawer")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.NumericEntry")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.NumericUpDown")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.OtpInput")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Picker")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Popup")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.ProgressBar")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.PullToRefresh")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.SegmentedControl")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Shimmer")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.TabView")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.TextInputLayout")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/dotnet/2021/maui", "Syncfusion.Maui.Toolkit.Themes")]
这样之后,我们以后可以直接使用,而不用自定义命名空间了。关于nupkg的本地安装,请大家通过下图箭头指处,配置目录。最后把编译好的NuGet本地包放入,安装正常安装就行。

3. 为了达到通过左边的导航切换Demo的效果,我们要写一些通用代码。这样,可以增强对不同项目共享View,ViewModel和Model的理解。

4. App.xaml的配置,其中MyStyles.xaml是一个ResourceDirectory(如下图)。这样我们之后所有的自定义Style模板,都可以放里面了。

<?xml version = "1.0" encoding = "UTF-8" ?> <Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MauiViews" x:Class="MauiViews.App"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources/Styles/Colors.xaml" /> <ResourceDictionary Source="Resources/Styles/Styles.xaml" /> <ResourceDictionary Source="/Resources/Styles/MyStyles.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
对应的cs代码如下
namespace MauiViews
{
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
}
}
5. 现在我们要完成AppShell.xaml的配置。
<?xml version="1.0" encoding="UTF-8" ?> <Shell x:Class="MauiViews.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MauiViews" Title="Maui" Shell.NavBarIsVisible="False"> </Shell>
对应的cs代码如下,关于Shell代码,我已经简化成扩展了,大家可以不用下面代码。参考https://www.cnblogs.com/dalgleish/p/18920441
using System.Diagnostics;
namespace MauiViews
{
public partial class AppShell : Shell
{
private bool isLoaded = false;
private readonly Dictionary<string, string> routesSamples = [];
public AppShell()
{
InitializeComponent();
PropertyChanged += AppShellPropertyChanged;
}
private void AppShellPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (isLoaded)
return;
isLoaded = true;
var samples = MauiViewModels.Index.Samples;
var i = 0;
for (var i1 = 0; i1 < samples.Length; i1++)
{
var item = samples[i1];
var t = Type.GetType($"MauiViews.{item.Replace('/', '.')}.View");
Routing.RegisterRoute(item, t);
var shellSection = new ShellSection { Title = item };
ShellContent content;
try
{
content = new ShellContent()
{
Content = (i == 0 ? Activator.CreateInstance(t!) : null)
};
}
catch (Exception)
{
throw;
}
shellSection.Items.Add(content);
Items.Add(shellSection);
routesSamples.Add("//" + content.Route, item);
i++;
}
Navigating += AppShellNavigate;
}
private void AppShellNavigate(object? sender, ShellNavigatingEventArgs e)
{
var shell = (AppShell?)sender ?? throw new Exception("未找到对应的Shell");
var r = shell.Items.Select(x => x.CurrentItem.CurrentItem.Route).ToArray();
var next = Items.FirstOrDefault(x => "//" + x.CurrentItem.CurrentItem.Route == e.Target.Location.OriginalString);
var item = routesSamples[e.Target.Location.OriginalString];
var t = Type.GetType($"MauiViews.{item.Replace('/', '.')}.View");
var i = Activator.CreateInstance(t!);
var c = next!.Items[0].Items[0];
c.Content = i;
}
}
}
其次,添加Index.cs文件到MauiViews项目下,之后添加的Demo,主页面都是默认View.xaml了。
namespace MauiViewModels
{
// All the code in this file is included in all platforms.
public static class Index
{
public static string[] Samples =
[
"MauiDemos/Demo1",
"MauiDemos/Demo2",
"MauiDemos/Demo3"
];
}
}
因为我正在把有些项目从WPF转到MAUI,所以你看到我的目前三个是这样的。

展示一个demo吧

6. 最后MauiProgram.cs如下
using Syncfusion.Maui.Toolkit.Hosting;
namespace MauiViews
{
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureSyncfusionToolkit()//配置SyncfusionToolkit
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
fonts.AddFont("IconFont.ttf", "IconFont");//这个自己去https://www.iconfont.cn/注册账号,和添加自己的Icon图标,然后下载下来覆盖IconFont.ttf就行啦。
fonts.AddFont("Roboto-Medium.ttf", "RobotoMedium");
fonts.AddFont("Roboto-Regular.ttf", "Roboto");
fonts.AddFont("SyncFontIcons.ttf", "SyncFontIcons");
fonts.AddFont("SegmentIcon.ttf", "SegmentIcon");
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
}
如果你没有这三个demo也没关系,上面是通用代码,只是为了之后我出教程的时候,方便切换各个demo而已。如果你嫌麻烦,可以每个demo都建一个项目,我比较懒,这样就可以在三个项目里,分别添加对应的代码了。
文中的demo学习是来自B站博主DotNET知识库,所以大家可以去看看他的视频,还有关于Maui Blazor等很多有用的项目开发。
但是本教程是基于《WPF编程宝典C#2012 第4版》,为了让更多人学习C#跨平台界面,但是不能保证更新时间。如果你需要转载,请务必转载齐全,并且把教程顺序做好,这样也方便更多人学习。
浙公网安备 33010602011771号