当前位置: 首页 > news >正文

【Maui】下拉框的实现,绑定键值对

文章目录

  • 前言
  • 一、问题描述
  • 二、解决方案
  • 三、软件开发(源码)
    • 3.1 创建模型
    • 3.2 视图界面
    • 3.3 控制器逻辑层
  • 四、项目展示![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/05795ee1c24c49129b822b530ef58302.png)


前言

.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 创建模型

文件名:MO1002AddViewModel.cs
位置:ViewModels
备注:集合一定要定义成 ObservableCollection,不要使用List,否则无法实现MVVM,ObservableCollection实现INotifyCollectionChanged, INotifyPropertyChanged。

using App.Mes.Core.Entities;
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 MO1002AddViewModel : INotifyPropertyChanged{private string _mtrlTypeValue; // 物料类型private string _houseValue; // 线边库private string _bnPlantValue; // 业务工厂private string _reasonValue; // 原因public ObservableCollection<KeyValuePair<string, string>> MtrlTypeOptions { get; set; } = new ObservableCollection<KeyValuePair<string, string>>();public ObservableCollection<KeyValuePair<string, string>> HouseOptions { get; set; } = new ObservableCollection<KeyValuePair<string, string>>();public ObservableCollection<KeyValuePair<string, string>> BnPlantOptions { get; set; } = new ObservableCollection<KeyValuePair<string, string>>();public ObservableCollection<KeyValuePair<string, string>> ReasonOptions { get; set; } = new ObservableCollection<KeyValuePair<string, string>>();public KeyValuePair<string, string> MtrlTypeValue{get => new KeyValuePair<string, string>(MtrlTypeOptions.FirstOrDefault(x => x.Value == _mtrlTypeValue).Key, _mtrlTypeValue);set{if (_mtrlTypeValue != value.Value){_mtrlTypeValue = value.Value;OnPropertyChanged();}}}public KeyValuePair<string, string> HouseValue{get => new KeyValuePair<string, string>(HouseOptions.FirstOrDefault(x => x.Value == _houseValue).Key, _houseValue);set{if (_houseValue != value.Value){_houseValue = value.Value;OnPropertyChanged();}}}public KeyValuePair<string, string> BnPlantValue{get => new KeyValuePair<string, string>(BnPlantOptions.FirstOrDefault(x => x.Value == _bnPlantValue).Key, _bnPlantValue);set{if (_bnPlantValue != value.Value){_bnPlantValue = value.Value;OnPropertyChanged();}}}public KeyValuePair<string, string> ReasonValue{get => new KeyValuePair<string, string>(ReasonOptions.FirstOrDefault(x => x.Value == _reasonValue).Key, _reasonValue);set{if (_reasonValue != value.Value){_reasonValue = value.Value;OnPropertyChanged();}}}/// <summary>/// 构造函数/// </summary>public MO1002AddViewModel(){InitializeOptions();}private void InitializeOptions(){//物料类型初始化MtrlTypeOptions.Add(new KeyValuePair<string, string>("22", "纸垛"));MtrlTypeOptions.Add(new KeyValuePair<string, string>("23", "纸卷"));MtrlTypeValue = MtrlTypeOptions.FirstOrDefault();//线边库初始化string str_house = GycMobileService.Proxy.GetHouseByUser();var houseList = JsonConvert.DeserializeObject<List<Tax0010>>(str_house);foreach (var item in houseList){HouseOptions.Add(new KeyValuePair<string, string>(item.CStoreHouse, item.CStoreHouseNm));}HouseValue = HouseOptions.FirstOrDefault();//业务工厂初始化string str_BnPlant = GycMobileService.Proxy.GetBsnsPlant();var BnPlantList = JsonConvert.DeserializeObject<List<Tax0002>>(str_BnPlant);foreach (var item in BnPlantList){BnPlantOptions.Add(new KeyValuePair<string, string>(item.CNewBnPlantCd, item.CNewBnPlantNm));}BnPlantValue = BnPlantOptions.FirstOrDefault();//退库原因string str_Reason = GycMobileService.Proxy.GetReason();var ReasonList = JsonConvert.DeserializeObject<List<KeyValuePair<string, string>>>(str_Reason);foreach (var item in ReasonList){ReasonOptions.Add(new KeyValuePair<string, string>(item.Key, item.Value));}ReasonValue = ReasonOptions.FirstOrDefault();}/// <summary>/// MO1002Page页面用,根据key获取value/// 备注:此方法不推荐,gyc建议服务端【联表查询】返回合适(有value)的数据对象,现在服务端ORM难以改造,故而使用此方案。/// </summary>public string GetMtrlTypeValueByKey(string key){var house = MtrlTypeOptions.FirstOrDefault(x => x.Key == key);return house.Value;}public string GetHouseValueByKey(string key){var house = HouseOptions.FirstOrDefault(x => x.Key == key);return house.Value;}public string GetBnPlantValueByKey(string key){var house = BnPlantOptions.FirstOrDefault(x => x.Key == key);return house.Value;}public string GetReasonValueByKey(string key){var house = ReasonOptions.FirstOrDefault(x => x.Key == key);return house.Value;}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged([CallerMemberName] string propertyName = null){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

3.2 视图界面

文件名:MO1002AddPage.xaml
位置:Pages
备注:第二种绑定形势,也可以在在逻辑层绑定。
<ContentPage.BindingContext>
<local:MO1002AddViewModel />
</ContentPage.BindingContext>

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="GlueNet.Mobile.Pages.MO1002AddPage"xmlns:local="clr-namespace:GlueNet.Mobile.ViewModels"Title="件次退料-制单"><ContentPage.BindingContext><local:MO1002AddViewModel /></ContentPage.BindingContext><VerticalStackLayout ><StackLayout Margin="10,20,10,20"><!--件次退料 制单--><Frame BorderColor="LightGray" CornerRadius="5" Padding="10" Margin="5"><Grid ColumnDefinitions="*,*" RowDefinitions="*,*,*,*"><Label Text="物料类型" VerticalOptions="Center"/><Picker Title="下拉框" Grid.Column="1" ItemsSource="{Binding MtrlTypeOptions}" SelectedItem="{Binding MtrlTypeValue}" ItemDisplayBinding="{Binding Value}"/><Label Text="线边库" Grid.Row="1" VerticalOptions="Center"/><Picker Title="下拉框" Grid.Row="1" Grid.Column="1" ItemsSource="{Binding HouseOptions}" SelectedItem="{Binding HouseValue}" ItemDisplayBinding="{Binding Value}"/><Label Text="业务工厂"  Grid.Row="2" VerticalOptions="Center"/><Picker Title="下拉框" Grid.Row="2" Grid.Column="1" ItemsSource="{Binding BnPlantOptions}" SelectedItem="{Binding BnPlantValue}" ItemDisplayBinding="{Binding Value}"/><Label Text="退库原因" Grid.Row="3" VerticalOptions="Center"/><Picker Title="下拉框" Grid.Row="3" Grid.Column="1" ItemsSource="{Binding ReasonOptions}" SelectedItem="{Binding ReasonValue}" ItemDisplayBinding="{Binding Value}"/></Grid></Frame></StackLayout><!--件次退料 制单--><Grid ColumnDefinitions="*,*,*"><Button Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" Text="确认"  FontSize="15" BackgroundColor="LightBlue" Clicked="OnAddClicked"/><Button Grid.Column="2" HorizontalOptions="Center" VerticalOptions="Center" Text="取消"  FontSize="15" BackgroundColor="Orange" Clicked="OnCanelClicked"/></Grid></VerticalStackLayout>
</ContentPage>

3.3 控制器逻辑层

逻辑层代码没有,全在ViewModel构造函数中,进行了数据初始化。
逻辑如果要使用可以使用如下方法

var viewModel = BindingContext as MO1002AddViewModel;

四、项目展示在这里插入图片描述

在这里插入图片描述

相关文章:

【Maui】下拉框的实现,绑定键值对

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 创建模型3.2 视图界面3.3 控制器逻辑层 四、项目展示![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/05795ee1c24c49129b822b530ef58302.png) 前言 .NET 多平台应用 UI (.NET MA…...

Oracle 深入学习 Part 14:Managing Password Security and Resources(管理密码安全性和资源)

Profiles Profile 是一个以名称标识的集合&#xff0c;用于管理 密码 和 资源限制。 每个用户都对应一个profiles&#xff0c;可以通过 CREATE USER 或 ALTER USER 命令分配给用户。 Profiles 可以启用或禁用。 Profiles 可以关联到默认的 DEFAULT Profile。 密码管理&…...

C语言:位段

位段的内存分配: 1. 位段的成员可以是 int unsigned int signed int 或者是char &#xff08;属于整形家族&#xff09;类型 2. 位段的空间上是按照需要以4个字节&#xff08; 类型 int &#xff09;或者1个字节&#xff08; char &#xff09;的方式来开辟的。 3. 位段涉及…...

MPLS VPN 原理与配置

一.简介 MPLS&#xff0c;称之为多协议标签交换&#xff0c;在九十年代中期被提出来&#xff0c;用于解决传统IP报文依赖查表转发而产生的瓶颈&#xff0c;现多用于VPN技术&#xff0c;MPLS报头封装在数据链路层之上&#xff0c;网络层之下。本文为结合了华为技术和新华三技术…...

稳定的通信桥梁,CCLINKIE转ModbusTCP网关实现AGV运输的光速效应

三菱PLC与AGV机器人搬运车通过稳联技术协议转换网关建立通信 一、现场情况概述 - 三菱PLC&#xff1a;使用CC-Link IE协议进行通信。 - AGV机器人搬运车&#xff1a;使用Modbus TCP协议进行通信。 - 协议转换网关&#xff1a;使用稳联技术的协议转换网关将PLC和AGV连接&#xf…...

Leetcode 3428. Maximum and Minimum Sums of at Most Size K Subsequences

Leetcode 3428. Maximum and Minimum Sums of at Most Size K Subsequences 1. 解题思路2. 代码实现 题目链接&#xff1a;3428. Maximum and Minimum Sums of at Most Size K Subsequences 1. 解题思路 这一题不需要连续性&#xff0c;因此我们就是考虑取得子串长度为别为1…...

第2章:Python TDD构建Dollar类基础

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

【算法学习笔记】34:扩展欧几里得算法

裴蜀定理 描述 对于任意正整数 a a a、 b b b&#xff0c;一定存在整数系数 x x x&#xff0c; y y y&#xff0c;使得&#xff1a; a x b y g c d ( a , b ) ax by gcd(a, b) axbygcd(a,b) 并且 g c d ( a , b ) gcd(a, b) gcd(a,b)是对于任意的系数 x x x和 y y y放在…...

云原生周刊:K8s 生产环境架构设计及成本分析

开源项目推荐 KubeZoneNet KubeZoneNet 旨在帮助监控和优化 Kubernetes 集群中的跨可用区&#xff08;Cross-Zone&#xff09;网络流量。这个项目提供了一种简便的方式来跟踪和分析 Kubernetes 集群中跨不同可用区的通信&#xff0c;帮助用户优化集群的网络架构、提高资源利用…...

WGAN - 瓦萨斯坦生成对抗网络

1. 背景与问题 生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;是由Ian Goodfellow等人于2014年提出的一种深度学习模型。它包括两个主要部分&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;…...

海量数据的处理

一般来说都是针对数据量特别大&#xff0c;内存有限制的。 第一类&#xff1a;topk问题 比如&#xff0c;在海量数据中找前50大的数据怎么办&#xff1f; 方法一&#xff1a;使用小顶堆&#xff0c;用小顶堆维护这50个元素&#xff0c;当有新元素到来时&#xff0c;直接与堆…...

区块链的数学基础:核心原理与应用解析

引言 区块链技术作为分布式账本系统&#xff0c;成功地解决了传统中心化系统中的信任问题。其背后隐藏着复杂而精妙的数学原理&#xff0c;包括密码学、哈希函数、数字签名、椭圆曲线、零知识证明等。这些数学工具不仅为区块链提供了安全保障&#xff0c;也为智能合约和去中心…...

1.5 GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新

GPT 模型家族全解析:从 GPT-1 到 GPT-4 的演进与创新 随着人工智能技术的飞速发展,GPT(Generative Pre-trained Transformer)模型家族已经成为了现代自然语言处理(NLP)领域的标杆。从初代的 GPT-1 到最新的 GPT-4,每一代模型的发布都标志着人工智能技术的一个飞跃,并推…...

自动驾驶之DriveMM: All-in-One Large Multimodal Model for Autonomous Driving

1. 写在前面 工作之后,主要从事于偏工程比较多的内容, 很少有机会读论文了,但2025年,由于之前有些算法的背景, 后面可能会接触一些多模态大模型相关的工作,所以又调头有点往算法的方向偏移, 而算法呢,很重要的一点就是阅读论文。2025年,再拾起论文这块的工作。 今天…...

Spring Boot 配置(官网文档解读)

目录 摘要 Spring Boot 配置加载顺序 配置文件加载顺序 Spring Boot 配置加载方式 Value Value 注解简单示例 ConfigurationProperties 启动 ConfigurationProperties ConfigurationProperties 验证 ConfigurationProperties 与 Value 对比 Autowired Autowired 自…...

SparkSQL数据源与数据存储

文章目录 1. 大数据分析流程2. Spark SQL数据源2.1 SparkSQL常见数据源2.2 SparkSQL支持的文本格式2.3 加载外部数据源步骤 3. 本地文件系统加载数据3.1 本地文件系统加载JSON格式数据3.1.1 概述3.1.2 案例演示 3.2 本地文件系统加载CSV格式数据3.2.1 概述3.2.2 案例演示 3.3 本…...

【BQ3568HM开发板】开箱测试

引言 很荣幸入选了“电子发烧友”的贝启科技BQ3568HM开源鸿蒙开发板评测活动&#xff0c;上周在出差&#xff0c;今天才有机会开箱一下开发板&#xff0c;简单测试一下。 开机测试 插上电源开机后&#xff0c;系统显示的是润和的DAYU的logo&#xff0c;看来厂商提供的软件包…...

3D 模型格式转换之 STP 转 STL 深度解析

在 3D 模型的多元世界中&#xff0c;格式如同语言&#xff0c;不同格式适用于不同场景。STP 和 STL 是两种常见格式&#xff0c;本文将深入剖析 STP 转 STL 的相关内容。 一、STP 与 STL 格式基础 &#xff08;一&#xff09;STP 格式剖析 STP&#xff0c;即标准交换格式&am…...

MySQL数据库的数据文件保存在哪?MySQL数据存在哪里

在安装好MySQL数据库使用一段时间后&#xff0c;会产生许多的数据库和数据。那这些数据库的数据文件存放在本地文件夹的什么位置呢 一、默认位置 一般来说MySQL数据库的数据文件都是存放在data文件夹之中&#xff0c;但是根据使用的存储引擎不同&#xff0c;产生的一些文件也…...

低代码系统-UI设计器核心介绍

为什么会有UI设计器 最开始的UI设计器其实是为了满足企业门户的需求而产生的&#xff0c;后面因为表单设计器的功能有限&#xff0c;所以干脆就用了一套设计器。 UI设计器从功能使用上来说&#xff0c;跟表单设计器没有多大区别&#xff0c;只是多了组件和加强了事件和组件的能…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

拟合问题处理

在机器学习中&#xff0c;核心任务通常围绕模型训练和性能提升展开&#xff0c;但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正&#xff1a; 一、机器学习的核心任务框架 机…...

Yii2项目自动向GitLab上报Bug

Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...