【Maui】動態菜單實現(綁定數據視圖)

前言

.NET 多平臺應用 UI (.NET MAUI) 是一個跨平臺框架,用于使用 C# 和 XAML 創建本機移動和桌面應用。
使用 .NET MAUI,可從單個共享代碼庫開發可在 Android、iOS、macOS 和 Windows 上運行的應用。

.NET MAUI 是一款開放源代碼應用,是 Xamarin.Forms 的進化版,從移動場景擴展到了桌面場景,并從頭重新生成了 UI 控件,以提高性能和可擴展性。 如果以前使用過 Xamarin.Forms 來生成跨平臺用戶界面,那么你會注意到它與 .NET MAUI 有許多相似之處。 但也有一些差異。 通過使用 .NET MAUI,可使用單個項目創建多平臺應用,但如果有必要,可以添加特定于平臺的源代碼和資源。 .NET MAUI 的主要目的之一是使你能夠在單個代碼庫中實現盡可能多的應用邏輯和 UI 布局。

一、問題描述

實現如下效果,菜單根據數據庫取數,自動加載。
在這里插入圖片描述

二、解決方案

創建數據模型
UserMenu.cs 用戶功能菜單,功能字、導航頁面名(后面使用反射可以實例化窗體)、圖標名。
UserMenu.cs 用戶模塊菜單,模塊下掛在用戶功能菜單。
MenuService.cs 業務邏輯單元,相應事件的處理,菜單數據初始化

三、詳細代碼

3.1 創建用戶菜單模型

二級菜單,功能級別的,UserMenu.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;namespace GlueNet.Mobile.Models
{public class UserMenu{/// <summary>/// 功能名/// </summary>public string Name { get; set; }/// <summary>/// 圖標名/// </summary>public string Icon { get; set; }/// <summary>/// 路由名/// </summary>public string Router { get; set; }/// <summary>/// 命令/// </summary>public ICommand Command { get; set; }}
}

3.2 創建用戶菜單視圖模型

一級菜單,模塊級別的,觀察者模式需要變更屬性,UserMenuViewModel.cs

using GlueNet.Mobile.Models;
using System.ComponentModel;
using System.Runtime.CompilerServices;namespace GlueNet.Mobile.ViewModels
{/// <summary>/// 實現INotifyPropertyChanged接口,觀察者模式/// 屬性改變通知綁定控件更新/// </summary>public class UserMenuViewModel : INotifyPropertyChanged{/// <summary>/// 模塊名/// </summary>private string _moduleName;/// <summary>/// 功能集合/// </summary>private List<UserMenu> _functions;/// <summary>/// 是否展開/// </summary>private bool _isExpanded;/// <summary>/// 展開/收起文本/// </summary>private string _expandedText;public string ModuleName{get => _moduleName;set{_moduleName = value;OnPropertyChanged();}}public List<UserMenu> Functions{get => _functions;set{_functions = value;OnPropertyChanged();}}public bool IsExpanded{get => _isExpanded;set{_isExpanded = value;OnPropertyChanged();}}public string ExpandedText{get => _expandedText;set{_expandedText = value;OnPropertyChanged();}}public event PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

3.3 創建用戶菜單服務方法

綁定事件、菜單數據初始化。

using GlueNet.Bussiness.Dtos;
using GlueNet.Bussiness;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ServiceModel.Channels;
using System.Windows.Input;
using GlueNet.Mobile.ViewModels;
using GlueNet.Mobile.Models;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Xml.Linq;
using System.Diagnostics.Metrics;namespace GlueNet.Mobile.BLL
{public class MenuService : BindableObject{public ObservableCollection<UserMenuViewModel> MenuGroups { get; set; }public ICommand ToggleExpandCommand { get; protected set; }public MenuService(){ToggleExpandCommand = new Command<UserMenuViewModel>(OnToggleExpand);GetMenuData();}private void OnToggleExpand(UserMenuViewModel menuGroup){if (menuGroup != null){menuGroup.IsExpanded = !menuGroup.IsExpanded;menuGroup.ExpandedText = menuGroup.IsExpanded ? "收起" : "展開";OnPropertyChanged(nameof(MenuGroups));}}/// <summary>/// 獲取菜單數據,從MES服務端獲取/// </summary>public void GetMenuData(){MenuGroups = new ObservableCollection<UserMenuViewModel>{new UserMenuViewModel{ModuleName = "質量管理",Functions = new List<UserMenu>{new UserMenu { Name = "質量1", Icon = "icon_quality.png", Router ="MO2001Page", Command = new Command(() => NavigateToPage("MO2001Page")) } ,new UserMenu { Name = "質量2", Icon = "icon_quality.png", Router = "MO2001Page",Command = new Command(() => NavigateToPage("MO2001Page")) },new UserMenu { Name = "質量3", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量4", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量5", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量6", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量7", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量8", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},new UserMenu { Name = "質量9", Icon = "icon_quality.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},},IsExpanded = true,ExpandedText = "收起"},new UserMenuViewModel{ModuleName = "采購管理",Functions = new List<UserMenu>{new UserMenu { Name = "采購1", Icon = "icon_supply.png", Router="MO2001Page", Command = new Command(() => NavigateToPage("MO2001Page")) } ,new UserMenu { Name = "采購2", Icon = "icon_supply.png", Router = "MO2001Page",Command = new Command(() => NavigateToPage("MO2001Page")) },new UserMenu { Name = "采購3", Icon = "icon_supply.png", Router = "MO2001Page" ,Command = new Command(() => NavigateToPage("MO2001Page"))},},IsExpanded = true,ExpandedText = "收起"},new UserMenuViewModel{ModuleName = "作業管理",Functions = new List<UserMenu>{new UserMenu { Name= "棧板下線", Icon= "icon_operation.png", Router="MO1001Page",Command = new Command(() => NavigateToPage("MO1001Page"))},new UserMenu { Name = "次件退庫", Icon = "icon_operation.png", Router = "MO1002Page",Command = new Command(() => NavigateToPage("MO1002Page")) }},IsExpanded = true,ExpandedText = "收起"}};}/// <summary>/// 使用反射,根據頁面名稱導航到指定頁面/// </summary>/// <param name="pageName"></param>/// <exception cref="ArgumentException"></exception>private async void NavigateToPage(string pageName){// 獲取對象名Type pageType = Type.GetType($"GlueNet.Mobile.Pages.{pageName}");if (pageType != null){//創建實例Page page = (Page)Activator.CreateInstance(pageType);await Application.Current.MainPage.Navigation.PushAsync(page);}else{throw new ArgumentException($"無法導航頁面: {pageName}");}}}
}

3.4 創建用戶菜單界面

xaml前段界面,需要使用模型綁定,和CollectionView遍歷,創建MenuView.xaml。

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:local="clr-namespace:GlueNet.Mobile.BLL"x:Class="GlueNet.Mobile.MenuView"><!--綁定上下文--><ContentView.BindingContext><local:MenuService /></ContentView.BindingContext><!--綁定字體資源,圖標已經生成字體庫--><ContentView.Resources><Style x:Key="NavButtonStyle" TargetType="RadioButton"><Setter Property="ControlTemplate"><ControlTemplate><Grid><Grid.RowDefinitions><RowDefinition/><RowDefinition Height="30" /></Grid.RowDefinitions><!--替換為圖標--><Label Text="{TemplateBinding Value}" FontFamily="Iconfont" FontSize="30" HorizontalOptions="Center"VerticalOptions="Center"></Label><!--替換為文字--><Label Text="{TemplateBinding Content}" Grid.Row="1" HorizontalOptions="Center"VerticalOptions="Center" FontSize="13"></Label></Grid></ControlTemplate></Setter></Style></ContentView.Resources><ScrollView><StackLayout><CollectionView ItemsSource="{Binding MenuGroups}"><CollectionView.ItemTemplate><DataTemplate><StackLayout><!-- 模塊名 --><Frame BorderColor="Gray" CornerRadius="5" Padding="5" Margin="5"><Grid ColumnDefinitions="*,60"><Label Text="{Binding ModuleName}" FontSize="Medium" FontAttributes="Bold" VerticalTextAlignment="Center"/><Button Grid.Column="1" Text="{Binding ExpandedText}" Command="{Binding Source={RelativeSource AncestorType={x:Type local:MenuService}}, Path=ToggleExpandCommand}" CommandParameter="{Binding .}" /></Grid></Frame><!-- 功能列表 --><StackLayout IsVisible="{Binding IsExpanded}"><CollectionView ItemsSource="{Binding Functions}" ItemsLayout="VerticalGrid,4"><CollectionView.ItemTemplate><DataTemplate><Grid Padding="5"><Grid.RowDefinitions><RowDefinition Height="*" /><RowDefinition Height="Auto" /></Grid.RowDefinitions><Frame BorderColor="LightGray" CornerRadius="5" Padding="10" Margin="5"><StackLayout Orientation="Vertical" HorizontalOptions="Center" VerticalOptions="Center" ><ImageButton Source="{Binding Icon}" HorizontalOptions="Center" Command="{Binding Command}" /><Label Text="{Binding Name}" FontSize="Medium" VerticalOptions="Center" HorizontalOptions="Center" Margin="10,0,0,0" /></StackLayout></Frame></Grid></DataTemplate></CollectionView.ItemTemplate></CollectionView></StackLayout></StackLayout></DataTemplate></CollectionView.ItemTemplate></CollectionView></StackLayout></ScrollView>
</ContentView>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65945.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65945.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65945.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Bash語言的語法糖

Bash語言的語法糖 引言 在現代編程語言中&#xff0c;“語法糖”是一個非常常見的術語&#xff0c;它指的是那些使代碼更加易讀、易寫的語法特性。盡管這些特性并不改變語言的功能&#xff0c;但它們能顯著提升開發者的編程體驗。在眾多編程語言中&#xff0c;Bash&#xff0…

linux---Nginx詳細教程(包含安裝,網站部署)

Nginx是一個高性能的HTTP和反向代理服務器&#xff0c;也可以用作郵件代理服務器&#xff0c;其以占有內存少、并發能力強、穩定性高、豐富的功能集、低系統資源消耗而聞名。以下是對Nginx的詳細教程&#xff1a; 一、Nginx簡介 Nginx由俄羅斯人開發&#xff0c;第一個公開版…

RNN之:LSTM 長短期記憶模型-結構-理論詳解-及實戰(Matlab向)

0.前言 遞歸&#xff01;循環神經網絡Recurrent Neural Network 循環神經網絡&#xff08;又稱遞歸神經網絡&#xff0c;Recurrent Neural Network&#xff0c;RNN&#xff09;。是一種用于處理序列數據的神經網絡結構&#xff0c;具有記憶功能&#xff0c;能夠捕捉序列中的時…

泛目錄和泛站有什么差別

啥是 SEO 泛目錄&#xff1f; 咱先來說說 SEO 泛目錄是啥。想象一下&#xff0c;你有一個巨大的圖書館&#xff0c;里面的書架上擺滿了各種各樣的書&#xff0c;每一本書都代表著一個網頁。而 SEO 泛目錄呢&#xff0c;就像是一個超級圖書管理員&#xff0c;它的任務就是把這些…

初識@ffmpeg/ffmpeg庫

前言 FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并且能夠利用它們來創建一個新的流媒體格式的自由軟件項目,它被廣泛應用在視頻處理、音頻處理以及直播領域。其中,@ffmpeg/ffmpeg 是一個將 FFmpeg 編譯為 WebAssembly(WASM)的庫,可支持幾乎所有的音視頻格式。 安裝…

【圖像去噪】論文復現:反向擴散中加入MAP將擴散模型從高斯去噪推廣到真實去噪!DiffusionVI的Pytorch源碼復現,跑通源碼,梳理理論,單卡可執行!

請先看【專欄介紹文章】:【圖像去噪(Image Denoising)】關于【圖像去噪】專欄的相關說明,包含適配人群、專欄簡介、專欄亮點、閱讀方法、定價理由、品質承諾、關于更新、去噪概述、文章目錄、資料匯總、問題匯總(更新中) 完整代碼和訓練好的模型權重文件下載鏈接見本文底…

Windows 藍牙驅動開發-簡介

藍牙(英語&#xff1a;Bluetooth)是一種無線通信技術標準&#xff0c;用來讓固定與移動設備&#xff0c;在短距離間交換資料&#xff0c;以形成個人局域網(PAN)。其使用短波特高頻(UHF)無線電波&#xff0c;經由2.4至2.485 GHz的ISM頻段來進行通信。1994年由電信商愛立信(Erics…

【Vue】全局/局部組件使用流程(Vue2為例)

全局組件和局部組件區別 如何使用 全局組件&#xff1a;全局注冊后&#xff0c;可以在任意頁面中直接使用。局部組件&#xff1a;在頁面中需要先導入子組件路徑&#xff0c;注冊組件才能使用。 適用場景 全局組件&#xff1a;適用于高頻使用的組件&#xff0c;如導航欄、業…

【Pytorch實用教程】PyTorch 中如何輸出模型參數:全面指南

文章目錄 PyTorch 中如何輸出模型參數:全面指南1. 為什么需要輸出模型參數?2. PyTorch 中輸出模型參數的方法2.1 使用 `model.parameters()` 輸出所有參數2.2 使用 `model.named_parameters()` 輸出參數名稱和值2.3 使用 `model.state_dict()` 輸出模型的參數字典2.4 輸出特定…

vscode vue 自動格式化

vscode vue 自動格式化 安裝Prettier和Vetur插件 選擇設置&#xff0c;并且轉到編輯文件。增加如下內容。 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","[vue]": {"editor.defaultFor…

1、docker概念和基本使用命令

docker概念 微服務&#xff1a;不再是以完整的物理機為基礎的服務軟件&#xff0c;而是借助于宿主機的性能。以小量的形式&#xff0c;單獨部署的應用。 docker&#xff1a;是一個開源的應用容器引擎&#xff0c;基于go語言開發的&#xff0c;使用時apache2.0的協議。docker是…

Genymotion配套VirtualBox所在地址

在 Genymotion打開虛擬機前需要先打開VirtualBox中的虛擬機 C:\Program Files\Oracle\VirtualBox\VirtualBox.exe 再開啟genymotion中的虛擬機開關

【Linux】深刻理解軟硬鏈接

一.軟硬鏈接操作 1.軟連接 touch 創建一個文件file.txt &#xff0c;對該文件創建對應的軟鏈接改怎么做呢&#xff1f; ln -s file.txt file-soft.link .給對應文件創建軟連接。 軟連接本質就是一個獨立的文件&#xff0c;因為我們對應的軟連接有獨立的inode&#xff0c;他…

linux下MySQL的數據存放

在 Linux 下安裝的 MySQL&#xff0c;數據表的數據默認存放在 My曉SQL 數據庫的**數據目錄**&#xff08;Data Directory&#xff09;中。具體來說&#xff0c;MySQL 會將所有數據庫的數據存儲在一個由 MySQL 配置文件中指定的目錄里。該目錄包含了所有數據庫的表、索引、日志等…

第三十六章 Spring之假如讓你來寫MVC——攔截器篇

Spring源碼閱讀目錄 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如讓你來寫IOC容器——加載資源篇 第三章 Spring之假如讓你來寫IOC容器——解析配置文件篇 第四章 Spring之假如讓你來寫IOC容器——XML配置文件篇 第五章 Spring之假如讓你來寫…

快速上手 HarmonyOS 應用開發

一、DevEco Studio 安裝與配置 1. DevEco Studio 簡介 DevEco Studio 是 HarmonyOS 的一站式集成開發環境&#xff08;IDE&#xff09;&#xff0c;提供了豐富的工具和功能&#xff0c;支持 HarmonyOS 應用開發的全流程。 2. DevEco Studio 下載與安裝 下載地址&#xff1a…

Java Web開發進階——錯誤處理與日志管理

錯誤處理和日志管理是任何生產環境中不可或缺的一部分。在 Spring Boot 中&#xff0c;合理的錯誤處理機制不僅能夠提升用戶體驗&#xff0c;還能幫助開發者快速定位問題&#xff1b;而有效的日志管理能夠幫助團隊監控應用運行狀態&#xff0c;及時發現和解決問題。 1. 常見錯誤…

圖解Git——分支的新建與合并《Pro Git》

?分支的新建與合并 先引入一個實際開發的工作流&#xff1a; 開發某個網站。為實現某個新的需求&#xff0c;創建一個分支。在這個分支上開展工作。 正在此時&#xff0c;你突然接到一個電話說有個很嚴重的問題需要緊急修補。你將按照如下方式來處理&#xff1a; 切換到你…

C#使用實體類Entity Framework Core操作mysql入門:從數據庫反向生成模型2 處理連接字符串

初級代碼游戲的專欄介紹與文章目錄-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代碼都將會位于ctfc庫中。已經放入庫中我會指出在庫中的位置。 這些代碼大部分以Linux為目標但部分代碼是純C的&#xff0c;可以在任何平臺上使用。 源碼指引&#xff1a;github源…

【數據可視化-12】數據分析崗位招聘分析

&#x1f9d1; 博主簡介&#xff1a;曾任某智慧城市類企業算法總監&#xff0c;目前在美國市場的物流公司從事高級算法工程師一職&#xff0c;深耕人工智能領域&#xff0c;精通python數據挖掘、可視化、機器學習等&#xff0c;發表過AI相關的專利并多次在AI類比賽中獲獎。CSDN…