如何安装网站,百度关键词搜索量查询,柳州 网站推广,zenm自己做网站文章目录 前言一、问题描述二、解决方案三、软件开发#xff08;源码#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言
.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架#xff0c;用于使用 C# 和 XAML 创建本机移动和桌面应用。 使用 .NET MAUI源码3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示 前言
.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 布局。
一、问题描述
MVVM模式Model-View-ViewModel架构模式是将View和ViewModel关联起来通过双向数据绑定实现View和ViewModel的同步更新。View负责展示数据和用户交互ViewModel负责处理数据和业务逻辑Model负责存储数据。MVVM的优点是能够降低View和ViewModel之间的耦合使得代码更加可维护和可测试。 .NET MAUI是如何进行将View和ViewModel双向绑定的呢
二、解决方案
1、视图–数据模型绑定定义ViewModels视图层通过Binding属性绑定ViewModels 2、数据模型–视图绑定ViewModels属性发生改变需要通知View进行更新通知采用观察者模式更新View采用委托Invoke。 听起来很复杂对不对其实很简单。
三、软件开发源码
3.1 创建模型 文件名TitleBarViewModel.cs 位置ViewModels 备注集合一定要定义成 ObservableCollection不要使用List否则无法实现MVVMObservableCollection实现INotifyCollectionChanged, INotifyPropertyChanged。 using App.Mes.Core.Operation.Services.Mobile;
using Newtonsoft.Json;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace GlueNet.Mobile.ViewModels
{public class TitleBarViewModel : INotifyPropertyChanged{private string _version;private string _workdate;private string _classesValue; //班组private string _userID;private string _userName;private string _userComb; // 用户编号姓名public ObservableCollectionKeyValuePairstring, string ClassesOptions { get; set; } new ObservableCollectionKeyValuePairstring, string();public string ClassesValue{get _classesValue;set{if (_classesValue ! value){_classesValue value;OnPropertyChanged();}}}public string Version{get _version;set{_version value;OnPropertyChanged();}}public string WorkDate{get _workdate;set{if (_workdate ! value){_workdate value;OnPropertyChanged();}}}public string UserID{get _userID;set{_userID value;OnPropertyChanged();}}public string UserName{get _userName;set{_userName value;OnPropertyChanged();}}public string UserComb{get _userComb;set{_userComb value;OnPropertyChanged();}}/// summary/// 构造函数/// /summarypublic TitleBarViewModel(){InitializeOptions();}private void InitializeOptions(){//取班组string str_Reason GycMobileService.Proxy.GetKeyValue(class_group);var ReasonList JsonConvert.DeserializeObjectListKeyValuePairstring, string(str_Reason);foreach (var item in ReasonList){ClassesOptions.Add(new KeyValuePairstring, string(item.Key, item.Value));}ClassesValue ClassesOptions.FirstOrDefault().Value;}/// summary/// 班组/// /summarypublic string GetClassesValueByKey(string key){var Classes ClassesOptions.FirstOrDefault(x x.Key key);return Classes.Value;}//实现了INotifyPropertyChanged接口用于在属性值发生变化时通知界面更新。public event PropertyChangedEventHandler PropertyChanged;//事件委托更新属性protected virtual void OnPropertyChanged([CallerMemberName] string propertyName null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
} 文件名MO1002DetailsModel.cs 位置ViewModels 备注集合一定要定义成 ObservableCollection不要使用List否则无法实现MVVMObservableCollection实现INotifyCollectionChanged, INotifyPropertyChanged。 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace GlueNet.Mobile.Models
{public class MO1002DetailsModel{/// summary/// 预留申请单主号/// /summary public virtual string CReservedNo { get; set; }/// summary/// 创建人/// /summary public virtual string Creator { get; set; }/// summary/// 创建人/// /summary public virtual string CreatorCn { get; set; }/// summary/// 创建时间/// /summary public virtual DateTime? CreateTime { get; set; }/// summary/// 创建时间/// /summary public virtual string CreateTimeText { get; set; }/// summary/// 单据类型(1 移库 2 领料 3退库)/// /summary public virtual string CReservedType { get; set; }/// summary/// 单据类型(1 移库 2 领料 3退库)/// /summary public virtual string CReservedTypeCn { get; set; }/// summary/// 物料类型 1-散料 2 纸卷(21大纸22小纸23纸垛26tissue半成品) 暂不用mtrl_type/// /summary public virtual string CMtrlType { get; set; }/// summary/// 物料类型 1-散料 2 纸卷(21大纸22小纸23纸垛26tissue半成品) 暂不用mtrl_type/// /summary public virtual string CMtrlTypeCn { get; set; }/// summary/// 发货实体库代码/// /summary public virtual string CSendStoreHouse { get; set; }/// summary/// 发货实体库代码/// /summary public virtual string CSendStoreHouseCn { get; set; }/// summary/// 发货业务工厂代码/// /summary public virtual string CSendBnPlantId { get; set; }/// summary/// 发货业务工厂/// /summary public virtual string CSendBnPlantIdCn { get; set; }/// summary/// 发货班次/// /summary public virtual string CClassRate { get; set; }/// summary/// 备注/// /summary public virtual string CRemark { get; set; }/// summary/// 备注/// /summary public virtual string CRemarkCn { get; set; }/// summary/// 是否被选中/// /summary public virtual bool IsCheck { get; set; } false;}
}
3.2 视图界面 文件名MO1002Page.xaml 位置Pages 备注使用ModeTwoWay使用双向绑定可以不设置观察者模式 遍历中的RadioButton不要使用CheckedChanged()属性亲测有bug在2条数据被删除1条数据时页面自然只剩1条数据RadioButton会自动被勾选但是不会触发CheckedChanged()不建议使用CheckedChanged()属性。 ?xml version1.0 encodingutf-8 ?
ContentPage xmlnshttp://schemas.microsoft.com/dotnet/2021/mauixmlns:xhttp://schemas.microsoft.com/winfx/2009/xamlx:ClassGlueNet.Mobile.Pages.MO1002PageTitle件次退料StackLayout!--顶部标题栏--Grid BackgroundColor{StaticResource Gray300} Padding5Grid.RowDefinitionsRowDefinition Height* //Grid.RowDefinitionsGrid.ColumnDefinitionsColumnDefinition Width* /ColumnDefinition Width* /ColumnDefinition Width* //Grid.ColumnDefinitions!-- 显示当前日期左边部分 --DatePicker x:NameHiddenDatePickerDate{Binding TitleBar.WorkDate}TextColorWhite Formatyyyy-MM-ddHorizontalOptionsStart VerticalOptionsCenter Grid.Column0 DateSelectedOnDateSelected /!-- 显示班组绑定点击事件 --Label Text{Binding TitleBar.ClassesValue}TextColorWhiteHorizontalOptionsCenterVerticalOptionsCenterGrid.Column1x:NameClassesLabelLabel.GestureRecognizersTapGestureRecognizer TappedOnClassesClicked //Label.GestureRecognizers/Label!-- 显示登录用户名绑定点击事件 --Label Text{Binding TitleBar.UserName}TextColorWhiteHorizontalOptionsCenterVerticalOptionsCenterGrid.Column2x:NameUserNameLabel/Label/Grid!--中部数据区域--ScrollView VerticalOptionsFillAndExpandCollectionView ItemsSource{Binding DataList} SelectionModeNoneCollectionView.ItemTemplateDataTemplateHorizontalStackLayout!--必须要否则前端有bug--RadioButton GroupNameDataListGroup IsChecked{Binding IsCheck, ModeTwoWay}/Frame BorderColorLightGray CornerRadius5 Padding10 Margin5Grid ColumnDefinitions*,*,*,* RowDefinitions*,*,*,*,*,*Label Grid.Column0 Text退库单号 FontSizeSmall /Label Grid.Column1 Grid.ColumnSpan3 Text{Binding CReservedNo} FontSizeSmall /Label Grid.Row1 Grid.Column0 Text单据类型 FontSizeSmall /Label Grid.Row1 Grid.Column1 Text{Binding CReservedTypeCn} FontSizeSmall/Label Grid.Row1 Grid.Column2 Text物料类型 FontSizeSmall /Label Grid.Row1 Grid.Column3 Text{Binding CMtrlTypeCn} FontSizeSmall/Label Grid.Row2 Grid.Column0 Text线边库 FontSizeSmall /Label Grid.Row2 Grid.Column1 Text{Binding CSendStoreHouseCn} FontSizeSmall/Label Grid.Row3 Grid.Column0 Text业务工厂 FontSizeSmall /Label Grid.Row3 Grid.Column1 Grid.ColumnSpan3 Text{Binding CSendBnPlantIdCn} FontSizeSmall/Label Grid.Row4 Grid.Column0 Text创建人 FontSizeSmall /Label Grid.Row4 Grid.Column1 Text{Binding CreatorCn} FontSizeSmall/Label Grid.Row4 Grid.Column2 Text创建时间 FontSizeSmall /Label Grid.Row4 Grid.Column3 Text{Binding CreateTimeText} FontSizeSmall/Label Grid.Row5 Grid.Column0 Text退库原因 FontSizeSmall /Label Grid.Row5 Grid.Column1 Grid.ColumnSpan3 Text{Binding CRemarkCn} FontSizeSmall //Grid/Frame/HorizontalStackLayout/DataTemplate/CollectionView.ItemTemplate/CollectionView/ScrollView!--底部操作栏--Grid HeightRequest60 Padding5 BackgroundColor{StaticResource Gray300}Grid.ColumnDefinitionsColumnDefinition Width* /ColumnDefinition Width* /ColumnDefinition Width* /ColumnDefinition Width* //Grid.ColumnDefinitionsButton HorizontalOptionsCenter Text刷新 FontSizeSmall BackgroundColorLightBlue ClickedOnRefreshClicked/Button Grid.Column1 HorizontalOptionsCenter Text制单 FontSizeSmall BackgroundColorGreen ClickedOnAddClicked/Button Grid.Column2 HorizontalOptionsCenter Text编辑 FontSizeSmall BackgroundColorYellowGreen ClickedOnEditClicked/Button Grid.Column3 HorizontalOptionsCenter Text删除 FontSizeSmall BackgroundColorRed ClickedOnDeleteClicked//Grid/StackLayout/ContentPage
3.3 控制器逻辑层
定义 private MO1002AllViewModel MO1002List { get; set; } new MO1002AllViewModel();界面绑定也可以在view层绑定 BindingContext MO1002List;数据初始化从服务端取数可以不看重点关注数据绑定 /// summary/// 刷新/// /summary/// param namesender/param/// param namee/paramprivate async void OnRefreshClicked(object sender, EventArgs e){try{//按工作日期、制单人查询string str_Result GycMobileService.Proxy.GetMasterTAX_2010(MO1002List.TitleBar.WorkDate, MO1002List.TitleBar.UserID);var var_MobileResult JsonConvert.DeserializeObjectMobileResult(str_Result);string aa var_MobileResult.RetValue.ToString();if (var_MobileResult.IsSuccess){MO1002List.DataList.Clear();ListTax2010? list_Tax2010 JsonConvert.DeserializeObjectListTax2010(var_MobileResult.RetValue.ToString());if (list_Tax2010 ! null list_Tax2010.Count 0){// 创建一个 MO1002AddViewModel 实例来获取线边库的名称var addViewModel new MO1002AddViewModel();foreach (var item in list_Tax2010){MO1002List.DataList.Add(new MO1002DetailsModel{CReservedNo item.CReservedNo,Creator item.Creator,CreatorCn MO1002List.TitleBar.UserName,//框架未知问题创建日期数据返回不对CreateTime item.CreateTime,CreateTimeText item.CreateTime.ToString(yyyy-MM-dd HH:MM:ss),//CreateTime item.LastModifyTime,//CreateTimeText item.LastModifyTime?.ToString(yyyy-MM-dd HH:mm:ss) ?? string.Empty,CReservedType item.CReservedType,CReservedTypeCn 退库,CMtrlType item.CMtrlType,CMtrlTypeCn addViewModel.GetMtrlTypeValueByKey(item.CMtrlType),CSendStoreHouse item.CSendStoreHouse,CSendStoreHouseCn addViewModel.GetHouseValueByKey(item.CSendStoreHouse),CSendBnPlantId item.CSendBnPlantId,CSendBnPlantIdCn addViewModel.GetBnPlantValueByKey(item.CSendBnPlantId),CClassRate item.CClassRate,CRemark item.CRemark,CRemarkCn addViewModel.GetReasonValueByKey(item.CRemark),});}}Toaster.Show(var_MobileResult.Remark);}else{await MessageExtension.Error(var_MobileResult.Remark);}}catch (Exception ex){Toaster.Show(ex.Message);return;}}获取选中的数据从集合中取被勾选的数据行。 /// summary/// 单选按钮选中事件/// /summary/// param namesender/param/// param e/paramprivate void OnRadioButtonCheckedChanged(){if (MO1002List.DataList ! null MO1002List.DataList.Count 0){MO1002List.SelectedDetail MO1002List.DataList.FirstOrDefault(x x.IsCheck true) ?? new MO1002DetailsModel();}}四、项目展示