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#跨平台界面,但是不能保证更新时间。如果你需要转载,请务必转载齐全,并且把教程顺序做好,这样也方便更多人学习。

 

posted on 2025-06-01 02:29  dalgleish  阅读(213)  评论(0)    收藏  举报