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

目标:

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

2、移动窗体。

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

效果:

 代码:

MauiProgram.cs代码如下:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .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<WeatherForecastService>();
        builder.Services.AddSingleton<ErrorLogs>();
        builder.Services.AddSingleton<ErrorLogsDatabase>();
        //builder.Services.AddSingleton<I18n>();

        // 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

<MApp Id="inspire">
    <MErrorHandler OnHandle="Callback">
        <CascadingValue Value="@I18n.Culture.ToString()" Name="Culture">
            <MNavigationDrawer Dark @bind-Value="_drawer" Absolute Temporary>
                <MListItem>
                    <MListItemAvatar>
                        <MImage Src="https://randomuser.me/api/portraits/men/78.jpg"></MImage>
                    </MListItemAvatar>

                    <MListItemContent>
                        <MListItemTitle>YIMO</MListItemTitle>
                    </MListItemContent>
                </MListItem>

                <MDivider></MDivider>
                
                <MList Dense>
                    <!--首页-->
                    <MBorder Value=false Offset Width=4 Class="rounded-r-1" Border="Borders.Right">
                        <MListItem Ripple=false Class="mb-4" ActiveClass="fill-lighten-1" Href="">
                            <ItemContent>
                                <MListItemIcon>
                                    <MIcon Size=20>mdi-view-dashboard</MIcon>
                                </MListItemIcon>
                                <MListItemContent>
                                    <div style="margin-left:5px;" class="text-truncate white-space:nowrap">@I18n.T("Home")</div>
                                </MListItemContent>
                            </ItemContent>
                        </MListItem>
                    </MBorder>
                    
                    <!--错误日志-->
                    <MBorder Value=false Offset Width=4 Class="rounded-r-1" Border="Borders.Right">
                        <MListItem Ripple=false Class="mb-4" ActiveClass="fill-lighten-1" Href="errorLogsPage">
                            <ItemContent>
                                <MListItemIcon>
                                    <MIcon Size=20>mdi-alert-circle-outline</MIcon>
                                </MListItemIcon>
                                <MListItemContent>
                                    <div style="margin-left:5px;" class="text-truncate white-space:nowrap">@I18n.T("ErrorLog")</div>
                                </MListItemContent>
                            </ItemContent>
                        </MListItem>
                    </MBorder>
                    <!--网络工具-->
                    <MListGroup PrependIcon="mdi-access-point">
                        <ActivatorContent>
                            <MListItemContent>
                                <div style="margin-left:5px;" class="text-truncate white-space:nowrap">@I18n.T("NetWorkTool")</div>
                             </MListItemContent>
                        </ActivatorContent>
                        <ChildContent>
                            <MBorder Value=false Offset Width=4 Class="rounded-r-1" Border="Borders.Right">
                                <MListItem Style="margin-left: 30px" Ripple=false ActiveClass="fill-lighten-1" Link Href="TCPServerToolsPage">
                                    <ItemContent>
                                        <MListItemIcon>
                                            <MIcon Size=20>mdi-access-point</MIcon>
                                        </MListItemIcon>
                                        <MListItemContent>
                                            <div style="margin-left: 5px;" class="text-truncate white-space:nowrap">@I18n.T("TCPServer")</div>
                                        </MListItemContent>
                                    </ItemContent>
                                </MListItem>
                            </MBorder>
                            <MBorder Value=false Offset Width=4 Class="rounded-r-1" Border="Borders.Right">
                                <MListItem Style="margin-left: 30px" Ripple=false ActiveClass="fill-lighten-1" Link Href="TCPClientToolsPage">
                                    <ItemContent>
                                        <MListItemIcon>
                                            <MIcon Size=20>mdi-access-point</MIcon>
                                        </MListItemIcon>
                                        <MListItemContent>
                                            <div style="margin-left: 5px;" class="text-truncate white-space:nowrap">@I18n.T("TCPClient")</div>
                                        </MListItemContent>
                                    </ItemContent>
                                </MListItem>
                            </MBorder>
                        </ChildContent>
                    </MListGroup>
                    
@*                    <!--首页-->
                    <MListItem Link href="">
                        <MListItemIcon>
                            <MIcon>mdi-view-dashboard</MIcon>
                        </MListItemIcon>

                        <MListItemContent>
                            <MListItemTitle>@I18n.T("Home")</MListItemTitle>
                        </MListItemContent>
                    </MListItem>
                    <!--错误日志-->
                    <MListItem Link href="errorLogsPage">
                        <MListItemIcon>
                            <MIcon>mdi-alert-circle-outline</MIcon>
                        </MListItemIcon>

                        <MListItemContent>
                            <MListItemTitle>@I18n.T("ErrorLog")</MListItemTitle>
                        </MListItemContent>
                    </MListItem>
                    <!--网络工具-->
                    <MListItem Link href="socketHelpToolPage">
                        <MListItemIcon>
                            <MIcon>mdi-access-point</MIcon>
                        </MListItemIcon>

                        <MListItemContent>
                            <MListItemTitle>@I18n.T("NetWorkTool")</MListItemTitle>
                        </MListItemContent>
                    </MListItem>*@
                </MList>
            </MNavigationDrawer>

            <MHover>
                <MAppBar Color="deep-purple accent-4" @onmouseup="OnMouseMove" @onmousemove="OnMouseMove" @onmousedown="OnMouseMove"
                         Dense
                         Dark App>
                    <MAppBarNavIcon @onclick="() => _drawer = !_drawer">
                    </MAppBarNavIcon>
                    <!--应用程序名称-->
                    <MToolbarTitle>
                        @*@I18n.T("ApplicationName")*@
                        @I18n.T("Home")
                    </MToolbarTitle>
                    <MSpacer></MSpacer>
                    <!--最小化-->
                    <MButton class="mx-2"
                             Fab
                             Small
                             Dark
                             Color="primary" @onclick="MinimizeWindow">
                        <MIcon>
                            mdi-minus
                        </MIcon>
                    </MButton>
                    <!--最大化-->
                    <MButton class="mx-2"
                             Fab
                             Small
                             Dark
                             Color="primary" @onclick="FullOrExitFullScreen">
                        <MIcon>
                            @Maximize
                        </MIcon>
                    </MButton>
                    <!--退出程序-->
                    <MButton class="mx-2"
                             Fab
                             Small
                             Dark
                             Color="primary" @onclick="()=> quitDialog = true">
                        <MIcon>
                            mdi-close
                        </MIcon>
                    </MButton>
                    <MDialog @bind-Value="quitDialog"
                             MaxWidth="290">
                        <MCard>
                            <MCardTitle Class="text-h5">
                                @I18n.T("Prompt")
                            </MCardTitle>

                            <MCardText>
                                @I18n.T("Do you want to quit the program?")
                            </MCardText>

                            <MCardActions>
                                <MSpacer></MSpacer>

                                <MButton Color="green darken-1"
                                         Text
                                         OnClick="QuitApplication">
                                    @I18n.T("Yes")
                                </MButton>

                                <MButton Color="green darken-1"
                                         Text
                                         OnClick="()=> quitDialog = false">
                                    @I18n.T("No")
                                </MButton>
                            </MCardActions>
                        </MCard>
                    </MDialog>
                    <MSwitch Class="mt-5 mr-10" @bind-Value="IsChinese" LeftText="EN" RightText="中" Color="black" TrackColor="#E5E6EB" MinHeight="30"></MSwitch>
                </MAppBar>
            </MHover>
            

            <MMain>
                <CascadingValue Value="this" IsFixed>
                    <!-- 给应用提供合适的间距 -->
                    <MContainer Fluid>
                        @Body
                    </MContainer>
                </CascadingValue>
            </MMain>
        </CascadingValue>
    </MErrorHandler>
</MApp>

@code {

    public static event EventHandler<MouseEventArgs> 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();
    }

    /// <summary>
    /// 是否隐藏任务栏
    /// </summary>
    private static bool isHideTaskBar = true;

    /// <summary>
    /// 是否最大化状态
    /// </summary>
    private static bool isMaximize = false;

    private static string Maximize = "mdi-window-maximize";
    /// <summary>
    /// 切换最大化状态
    /// </summary>
    private static void FullOrExitFullScreen()
    {
        if (!isMaximize)
        {
            WindowsHelper.FullScreen(isHideTaskBar);
            isMaximize = true;
            Maximize = "mdi-window-restore";
        }
        else
        {
            WindowsHelper.ExitFullScreen();
            isMaximize = false;
            Maximize = "mdi-window-maximize";
        }
    }

    /// <summary>
    /// 是否弹出退出应用程序对话框
    /// </summary>
    private bool quitDialog = false;
    /// <summary>
    /// 退出应用程序
    /// </summary>
    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();
        /// <summary>
        /// 判断属性是否已经初始化
        /// </summary>
        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
        }

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

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

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

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

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

        /// <summary>
        /// 退出全屏
        /// </summary>
        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
        }

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

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public static void Move(int x, int y)
        {
#if WINDOWS
            if (!isInit)
            {
                InitWindowsHelper();
            }
            appWindow.SetPresenter(customOverlappedPresenter);
            appWindow.Move(new PointInt32(x, y));
#endif
        }

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

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

#else
                        return -1;
#endif
            }
        }
    }

修改Windows外的滚动条:

 添加代码如下:

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);
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
要创建 MAUI Blazor 安卓应用的登录界面,可以按照以下步骤进行: 1. 在你的 MAUI Blazor 应用中创建一个新的 Razor 页面,命名为 Login.razor。 2. 在 Login.razor 文件中,添加一个包含用户名和密码输入框的表单。例如: ``` <form> <label for="username">用户名:</label> <input type="text" id="username" name="username"><br><br> <label for="password">密码:</label> <input type="password" id="password" name="password"><br><br> <button type="submit">登录</button> </form> ``` 3. 在 Login.razor 文件中添加一个事件处理程序,以响应表单提交事件。例如: ``` @code { private string username; private string password; private void OnSubmit() { // 在这里处理表单提交事件 } } ``` 4. 在 OnSubmit() 方法中,可以使用 C# 代码验证用户输入的用户名和密码,并根据验证结果执行相应的操作。例如,可以将用户重定向到应用的主页,或者显示一条错误消息。 ``` private void OnSubmit() { if (username == "admin" && password == "password") { // 用户名和密码验证通过,将用户重定向到应用的主页 NavigationManager.NavigateTo("/main"); } else { // 显示一条错误消息 errorMessage = "用户名或密码不正确"; } } ``` 5. 最后,在 Login.razor 文件中添加一个 @page 指令,以将该页面作为应用的登录页面。例如: ``` @page "/login" ``` 这样,在应用启动时,就会自动跳转到 Login 页面,并显示登录表单。用户输入用户名和密码后,点击“登录”按钮时,表单提交事件将触发 OnSubmit() 方法,进行验证和处理。如果用户名和密码验证通过,应用将自动跳转到主页。否则,将在页面上显示一条错误消息。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为风而战

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值