MAUI 第六天 使用MASA Blazor 处理界面相关问题

目标:

1、去掉Window自带的标题栏。

2、移动窗体。

3、实现最小化、最大/正常、退出应用、隐藏滚动条:

效果:

 代码:

MauiProgram.cs代码如下:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp()
            .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); })
            .ConfigureLifecycleEvents(events =>
            {
#if WINDOWS
                                      events.AddWindows(windows => windows.OnWindowCreated(window =>
                                      {
                                          //window.SizeChanged += OnSizeChanged;
                                          MauiWinUIWindow mauiwin = window as MauiWinUIWindow;
                                          if (mauiwin == null) { return; }

                                          //关闭扩展内容
                                          mauiwin.ExtendsContentIntoTitleBar = false;
                                          //mauiwin.Title = "Hello Maui";


                                          //通过maui窗口句柄获取appwindow---
                                          ///这里有个操蛋的东西我用最新版新建的工程没法直接getappwindow所以用了文章里的方法
                                          var wndId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(mauiwin.WindowHandle);
                                          Microsoft.UI.Windowing.AppWindow appwin = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(wndId);
                                          
                                          //对于OverlappedPresenter的解释文档在这个网址
                                          //https://learn.microsoft.com/zh-tw/windows/windows-app-sdk/api/winrt/microsoft.ui.windowing.overlappedpresenter?view=windows-app-sdk-1.2

                                          //大致就是OverlappedPresenter会设置这个窗口,这个窗口可以和其他窗口重叠,并对窗口标题栏 状态栏 工作栏进行设置,以及其他一些调整窗口的操作
                                          //var customOverlappedPresenter = Microsoft.UI.Windowing.OverlappedPresenter.CreateForContextMenu();
                                          //appwin.SetPresenter(customOverlappedPresenter);
                                      }));
#endif
            });


        builder.Services.AddMauiBlazorWebView();
#if DEBUG
        builder.Services.AddBlazorWebViewDeveloperTools();
#endif

        builder.Services.AddSingleton();
        builder.Services.AddSingleton();
        builder.Services.AddSingleton();
        //builder.Services.AddSingleton();

        // Add services to the container.
        builder.Services.AddMasaBlazor();
        builder.Services.AddMasaBlazor().AddI18nForMauiBlazor("wwwroot/i18n");

        return builder.Build();
    }
}

MainLayout.razor代码如下:

@using BlazorComponent.I18n
@using System.Globalization
@using BlazorComponent
@using BlazorComponent.Web
@using System.Diagnostics
@inherits LayoutComponentBase
@inject I18n I18n
@inject ErrorLogsDatabase errorLogsDatabase
@inject IPopupService PopupService
@inject IJSRuntime JsRuntime


    
        
            
                
                    
                        
                    

                    
                        YIMO
                    
                

                
                
                
                    
                    
                        
                            
                                
                                    mdi-view-dashboard
                                
                                
                                    
@I18n.T("Home")
mdi-alert-circle-outline
@I18n.T("ErrorLog")
@I18n.T("NetWorkTool")
mdi-access-point
@I18n.T("TCPServer")
mdi-access-point
@I18n.T("TCPClient")
@* mdi-view-dashboard @I18n.T("Home") mdi-alert-circle-outline @I18n.T("ErrorLog") mdi-access-point @I18n.T("NetWorkTool") *@
@*@I18n.T("ApplicationName")*@ @I18n.T("Home") mdi-minus @Maximize mdi-close @I18n.T("Prompt") @I18n.T("Do you want to quit the program?") @I18n.T("Yes") @I18n.T("No") @Body
@code { public static event EventHandler MouseMoveWindowEventHandler; private CultureInfo? _culture; private bool _showMobileMenuList; private bool _hideAppBarNavIcon; private bool _showSettings; private string? _project; bool _drawer = false; bool _isChinee = true; public bool IsChinese { get { return _isChinee; } set { _isChinee = !_isChinee; SetLanugae(); } } private void SetLanugae() { if (_isChinee) { I18n.SetCulture(new CultureInfo("zh-CN")); //将语言切换成zh-CN } else { I18n.SetCulture(new CultureInfo("en-US")); //将语言切换成zh-CN } } private async void Callback(Exception obj) { await errorLogsDatabase.SaveErrorLogsAsync(new ErrorLogs() { ErrorInformation = obj.Message }); PopupService.EnqueueSnackbarAsync(obj.Message, AlertTypes.Error); } private bool isMouseMove = false; //鼠标开始的位置 private double x = -1; private double y = -1; private void OnMouseMove(MouseEventArgs e) { if (e.Buttons.Equals(1) && isMouseMove) //按住鼠标移动 { WindowsHelper.Move(Convert.ToInt32(WindowsHelper.GetPositionX - x + e.ScreenX), Convert.ToInt32(WindowsHelper.GetPositionY - y + e.ScreenY)); } //Debug.WriteLine("当前鼠标状态:" + e.Buttons.ToString()); //Debug.WriteLine("窗体位置X:" + WindowsHelper.GetPositionX+ "Y:" + WindowsHelper.GetPositionY); if (e.Buttons.Equals(1) && !isMouseMove)//获取鼠标点击鼠标左键的点 { Debug.WriteLine("点击鼠标左键X:" + e.ScreenX + "Y:" + e.ScreenY); isMouseMove = true; //记录鼠标开始的位置 x = e.ScreenX; y = e.ScreenY; Debug.WriteLine("点击鼠标左键的屏幕当前位置X:" + WindowsHelper.GetPositionX + "Y:" + WindowsHelper.GetPositionY); } if (!e.Buttons.Equals(1) && isMouseMove)//获取鼠标左键松开的点 { Debug.WriteLine("鼠标左键松开X:" + e.ScreenX + "Y:" + e.ScreenY); isMouseMove = false; x = -1; y = -1; Debug.WriteLine("鼠标左键松开的屏幕当前位置X:" + WindowsHelper.GetPositionX + "Y:" + WindowsHelper.GetPositionY); } } private void MinimizeWindow() { WindowsHelper.MinimizeWindow(); } /// /// 是否隐藏任务栏 /// private static bool isHideTaskBar = true; /// /// 是否最大化状态 /// private static bool isMaximize = false; private static string Maximize = "mdi-window-maximize"; /// /// 切换最大化状态 /// private static void FullOrExitFullScreen() { if (!isMaximize) { WindowsHelper.FullScreen(isHideTaskBar); isMaximize = true; Maximize = "mdi-window-restore"; } else { WindowsHelper.ExitFullScreen(); isMaximize = false; Maximize = "mdi-window-maximize"; } } /// /// 是否弹出退出应用程序对话框 /// private bool quitDialog = false; /// /// 退出应用程序 /// private static void QuitApplication() { WindowsHelper.QuitApplication(); } }

WindowsHelper.cs代码如下:

    public static class WindowsHelper
    {

#if WINDOWS
        public static Window _Window;
        public static Object? nativeWindow;
        public static IntPtr windowHandle;
        public static WindowId WindowId;
        public static AppWindow appWindow;
        public static OverlappedPresenter p;
        public static OverlappedPresenter customOverlappedPresenter = Microsoft.UI.Windowing.OverlappedPresenter.CreateForContextMenu();
        /// 
        /// 判断属性是否已经初始化
        /// 
        public static bool isInit=false;
#endif
        public static void InitWindowsHelper()
        {
#if WINDOWS
            _Window = App.Current.Windows.First();
            nativeWindow = _Window.Handler.PlatformView;
            windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(nativeWindow);
            WindowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
            appWindow = AppWindow.GetFromWindowId(WindowId);
            p = appWindow.Presenter as OverlappedPresenter;
            isInit=true;
#endif
        }

        /// 
        /// 最小化窗体
        /// 
        public static void MinimizeWindow()
        {
#if WINDOWS
            
            if (!isInit)
            {
                InitWindowsHelper();
            }

            PInvoke.User32.ShowWindow(windowHandle, PInvoke.User32.WindowShowStyle.SW_MINIMIZE);
#endif
        }

        /// 
        /// 全屏显示
        /// 
        public static void FullScreen(bool isHideTaskBar)
        {
#if WINDOWS
            if (!isInit)
            {
                InitWindowsHelper();
            }

            if (isHideTaskBar)
            {
                appWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
            }

            if (p != null)
            {
                p.Maximize();
            }
#endif
        }

        /// 
        /// 退出全屏
        /// 
        public static void ExitFullScreen()
        {
#if WINDOWS
            if (!isInit)
            {
                InitWindowsHelper();
            }

            switch (appWindow.Presenter)
            {
                case OverlappedPresenter p:
                    p.Restore();
                    break;
                default:
                    appWindow.SetPresenter(AppWindowPresenterKind.Default);
                    break;
            }
            appWindow.SetPresenter(customOverlappedPresenter);
#endif
        }

        /// 
        /// 退出应用程序
        /// 
        public static void QuitApplication()
        {
            Application.Current.Quit();
        }

        /// 
        /// 
        /// 
        /// 
        /// 
        public static void Move(int x, int y)
        {
#if WINDOWS
            if (!isInit)
            {
                InitWindowsHelper();
            }
            appWindow.SetPresenter(customOverlappedPresenter);
            appWindow.Move(new PointInt32(x, y));
#endif
        }

        /// 
        /// 获取窗体的X
        /// 
        public static int GetPositionX
        {
            get
            {
#if WINDOWS
                if (!isInit)
                {
                    InitWindowsHelper();
                }
                return appWindow.Position.X;

#else
                        return -1;
#endif
            }
        }
        /// 
        /// 获取窗体的Y
        /// 
        public static int GetPositionY
        {
            get
            {
#if WINDOWS
                if (!isInit)
                {
                    InitWindowsHelper();
                }
                return appWindow.Position.Y;

#else
                        return -1;
#endif
            }
        }
    }

修改Windows外的滚动条:

MAUI 第六天 使用MASA Blazor 处理界面相关问题_第1张图片

 添加代码如下:

html::-webkit-scrollbar {
    display: none;
}

app.css代码如下:

@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background-color: rebeccapurple;
}

html::-webkit-scrollbar {
    display: none;
}

    h1:focus {
        outline: none;
    }

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

.blazor-error-boundary::after {
    content: "An error has occurred."
}

.status-bar-safe-area {
    display: none;
}



@supports (-webkit-touch-callout: none) {
    .status-bar-safe-area {
        display: flex;
        position: sticky;
        top: 0;
        height: env(safe-area-inset-top);
        background-color: #f7f7f7;
        width: 100%;
        z-index: 1;
    }

	.flex-column, .navbar-brand {
		padding-left: env(safe-area-inset-left);
	}
}

你可能感兴趣的:(microsoft,ui,windows)