适用于初学者的 .NET MAUI

news2024/11/19 9:33:53

适用于初学者的 .NET MAUI | Microsoft Learn

记录微软Learn中用到的代码。文章比较粗糙,大部分是项目代码粘贴。想详细学习的可到上面的链接学习,代码可以从这里复制后直接运行。

练习中一共有两个页面:

1、MainPage.xaml 用于添加列表中的内容。主要功能有向列表中添加一项;左滑删除该项;点击该选项进入详情页面。

2、DetailPage.xaml 显示详细信息,实际上显示的很少。返回主界面。

用到的MVVM包有:

1、CommunityToolkit.Mvvm

接下来是MainPage.xaml代码:

<?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="MauiAppDemo1.MainPage"
             xmlns:viewmode="clr-namespace:MauiAppDemo1.ViewModel"
             x:DataType="viewmode:MainViewModel">

    <Grid RowDefinitions="100,Auto,*"
          ColumnDefinitions=".75*,.25*"
          Padding="10"
          RowSpacing="10"
          ColumnSpacing="10">
        
        <Image Grid.ColumnSpan="2"
               Source="dotnet_bot.png"
               Background="white"/>
        
        <Entry Placeholder="Enter task"
               Text="{Binding Text}"
               Grid.Row="1"/>
        
        <Button Text="Add"
                Command="{Binding AddCommand}"
                Grid.Row="1"
                Grid.Column="1"/>

        <CollectionView Grid.Row="2" Grid.ColumnSpan="2"
                        ItemsSource="{Binding Items}"
                        SelectionMode="None">
            <!--<CollectionView.ItemsSource>
                <x:Array Type="{x:Type x:String}">
                    <x:String>Apples</x:String>
                    <x:String>Bananas</x:String>
                    <x:String>Oranges</x:String>
                </x:Array>
            </CollectionView.ItemsSource>-->
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="{x:Type x:String}">
                    <SwipeView>
                        <SwipeView.RightItems>
                            <SwipeItems>    
                                <SwipeItem Text="Delete"
                                           BackgroundColor="Red"
                                           Command="{Binding Source={RelativeSource AncestorType={x:Type viewmode:MainViewModel}},Path=DeleteCommand}"
                                           CommandParameter="{Binding .}"/>
                            </SwipeItems>
                        </SwipeView.RightItems>
                        <Grid Padding="0,5">
                            <Frame>
                                <Frame.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmode:MainViewModel}},Path=TapCommand}"
                                                          CommandParameter="{Binding .}"/>
                                </Frame.GestureRecognizers>
                                <Label Text="{Binding .}"
                                       FontSize="24"/>
                            </Frame>
                        </Grid>
                    </SwipeView>

                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </Grid>

</ContentPage>
using MauiAppDemo1.ViewModel;

namespace MauiAppDemo1;

public partial class MainPage : ContentPage
{
	int count = 0;

	public MainPage(MainViewModel vm)
	{
		InitializeComponent();
        BindingContext = vm;

    }

}

    using MauiAppDemo1.ViewModel;

namespace MauiAppDemo1;

public static class MauiProgram
{
	public static MauiApp CreateMauiApp()
	{
		var builder = MauiApp.CreateBuilder();
		builder
			.UseMauiApp<App>()
			.ConfigureFonts(fonts =>
			{
				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
				fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
			});

        builder.Services.AddSingleton<MainPage>();
        builder.Services.AddSingleton<MainViewModel>();

        builder.Services.AddTransient<DetailPage>();
		builder.Services.AddSingleton<DetailViewModel>();		

		return builder.Build();
	}
}
namespace MauiAppDemo1;

public partial class AppShell : Shell
{
	public AppShell()
	{
		InitializeComponent();

		Routing.RegisterRoute(nameof(DetailPage),typeof(DetailPage));
	}
}
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MauiAppDemo1.ViewModel
{
    /// <summary>
    /// CommunityToolkit.Mvvm
    /// </summary>
    public partial class MainViewModel : ObservableObject
    {

        public MainViewModel()
        {
            items = new ObservableCollection<string>();
        }

        [ObservableProperty]

        ObservableCollection<string> items;

        [ObservableProperty]
        string text;

        [RelayCommand]
        void Add()
        {
            if (string.IsNullOrWhiteSpace(Text)) return;

            items.Add(Text);

            Text = string.Empty;
        }

        [RelayCommand]

        void Delete(string s)
        {
            if (items.Contains(s))
            {
                items.Remove(s);
            }
        }

        [RelayCommand]  
        async Task Tap(string s)
        {
            await Shell.Current.GoToAsync($"{nameof(DetailPage)}?Text={s}");
        }
    }

    /// <summary>
    /// 基本写法
    /// </summary>
    //public class MainViewModel : INotifyPropertyChanged
    //{
    //    string text;

    //    public string Text
    //    {
    //        get => text;
    //        set
    //        {
    //            text=value;
    //            OnPropertyChanged(nameof(Text));
    //        }
    //    }

    //    public event PropertyChangedEventHandler PropertyChanged;
    //    void OnPropertyChanged(string name)=>PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    //}
}

DetailPage.xaml

                

<?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="MauiAppDemo1.DetailPage"
             xmlns:viewmodel="clr-namespace:MauiAppDemo1.ViewModel"
             x:DataType="viewmodel:DetailViewModel"
             Title="DetailPage">
    <VerticalStackLayout Padding="20">
        <Label 
            Text="{Binding Text}"
            FontSize="25"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />

        <Button Text="Go Back"
                Command="{Binding GoBackCommand}"/>
    </VerticalStackLayout>
</ContentPage>
using MauiAppDemo1.ViewModel;

namespace MauiAppDemo1;

public partial class DetailPage : ContentPage
{
	public DetailPage(DetailViewModel vm)
	{
		InitializeComponent();
        BindingContext = vm;
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MauiAppDemo1.ViewModel
{
    [QueryProperty("Text","Text")]
    public partial class DetailViewModel:ObservableObject
    {
        [ObservableProperty]
        string text;

        [RelayCommand]
        async Task GoBack()
        {
            await Shell.Current.GoToAsync("..");
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199899.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络安全之认识托管威胁检测与响应(MDR)

随着数字化转型加速&#xff0c;企业的IT环境日益复杂&#xff0c;面临的网络安全威胁也在不断增加。传统的防御措施已经无法有效应对新型威胁&#xff0c;而且很多企业缺乏专业的网络安全团队和技术手段&#xff0c;导致大量的安全事件未能及时被发现和处理。 在这种背景下&a…

如何安装Node.js? 创建Vue脚手架

1.进入Node.js官网&#xff0c;点击LTS版本进行下载 Node.js (nodejs.org)https://nodejs.org/en 2.然后一直【Next】即可 3.打开【cmd】,输入【node -v】注意node和-v中间的空格 查看已安装的Node.js的版本号&#xff0c;如果可以看到版本号&#xff0c;则安装成功 创建Vue脚手…

Flutter实践一:package组织

1.架构概览 为了降低Flutter工程里lib的复杂度&#xff0c;应尽量拆分一些代码成为独立的package。如图&#xff1a; 我们将通用的组件、领域模型、API、features、存储、repository等抽取成了单独的package。这时lib只剩下多国语言、基本的页面、路由等代码了&#xff1a; 这…

Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例

Flutter笔记 使用Flutter构建响应式PC客户端/Web页面-案例 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/detai…

Python基础入门例程53-NP53 前10个偶数(循环语句)

最近的博文&#xff1a; Python基础入门例程52-NP52 累加数与平均值(循环语句)-CSDN博客 Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 目录 最近的博文&#xff1a; 描…

TCSVT(IEEE Transactions on Circuits and Systems for Video Technology)期刊投稿指南

目录 TCSVT 期刊简介 TCSVT 期刊影响因子和分区​ 期刊官方网站 期刊投稿网址 投稿指南网址 稿件格式要求 稿件提交指南 A. 提交稿件 B. 手稿格式 C. 摘要指南 D. 提交图形的指南 E. 页面和彩色图形费用 TCSVT 期刊简介 IEEE Transactions on Circuits and Systems…

RGB颜色空间与BMP格式图片

RGB颜色空间 RGB可以分为两大类&#xff1a;一种是索引形式&#xff0c;一种是像素形式&#xff1a; 索引形式&#xff1a;存储每个像素在调色板中的索引 RGB1&#xff1a;每个像素用1bit表示&#xff0c;调色板中只包含两种颜色&#xff08;黑白&#xff09;RGB4&#xff1a…

恒源云之oss上传数据、云台下载数据

目录 一、本地cmd上传数据二、使用云平台下载数据 一、本地cmd上传数据 需要下载恒源云客户端oss需要先将数据&#xff08;代码、数据集&#xff09;压缩成zip文件。 本地cmd打开oss&#xff0c;测试是否安成功 oss输入oss命令&#xff0c;并正确输入账号密码 oss login在个人…

按键编程 pal库和标准库

按钮的电路设计 电路的搭建 原理与编程 创建了两个变量 用来捕捉按键的状态 先让两个变量都为1 previous和current都为1 &#xff08;按键没按下&#xff09; 然后让current去捕捉按键的状态通过读gpioA的pin0 如果为0就是按键按下 如果为1就是按键没按下 然后赋值给current …

U-Boot 图形化配置及其原理

目录 U-Boot 图形化配置体验menuconfig 图形化配置原理make menuconfig 过程分析Kconfig 语法简介 添加自定义菜单 在前两章中我们知道uboot 可以通过mx6ull_alientek_emmc_defconfig 来配置&#xff0c;或者通过文件mx6ull_alientek_emmc.h 来配置uboot。还有另外一种配置uboo…

理解快速排序

理解快速排序 首先了解以下快速排序 快速排序&#xff08;QuickSort&#xff09;是一种常用的排序算法&#xff0c;属于比较排序算法的一种。它是由英国计算机科学家Tony Hoare于1960年提出的&#xff0c;是一种分而治之&#xff08;divide and conquer&#xff09;的算法。 …

systemd-timesyncd

介绍 systemd-timesyncd 是一个用于跨网络同步系统时钟的守护服务。它实现了一个 SNTP 客户端。与NTP的复杂实现相比&#xff0c;这个服务简单的多&#xff0c;它只专注于从远程服务器查询然后同步到本地时钟。除非你打算为客户端提供 NTP 服务器或者连接本地硬件时钟&#xff…

Keras实现图注意力模型GAT

简介&#xff1a;本文实现了一个GAT图注意力机制的网络层&#xff0c;可以在Keras中像调用Dense网络层、Input网络层一样直接搭积木进行网络组合。 一&#xff0c;基本展示 如下图所示&#xff0c;我们输入邻接矩阵和节点特征矩阵之后&#xff0c;可以直接调用myGraphAttention…

第90步 深度学习图像分割:U-Net建模

基于WIN10的64位系统演示 一、写在前面 从这一期开始&#xff0c;我们杀个回马枪&#xff0c;继续学习深度学习图像分割系列&#xff0c;以为4090上岗了。 图像分割是计算机视觉的一个重要任务&#xff0c;目的是将数字图像分割成多个部分或区域&#xff0c;这些部分通常对应…

大话IEC104 规约

2. iec104 协议的帧结构 iec104 基于TCP/IP 传输&#xff0c;是一个应用层协议&#xff0c; 其帧结构被称为 APDU&#xff0c;APDU 一般由 APCI 和 ASDU组成。 2.1 APDU (Application Protocol Data Unit) APDU 被称为应用协议数据单元&#xff0c;也就是一个iec104 的协议帧…

详解—搜索二叉树

一.二叉搜索树 1.1概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 它的…

Android修行手册 - 可变参数中星号什么作用(冷知识)

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

No183.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

【MySQL系列】 第一章 · MySQL概述

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Visual Studio 2019 写 Unity 脚本时,烦人又离谱的自动补全!

Visual Studio 2019 写 Unity 脚本时&#xff0c;逆天又离谱的自动补全&#xff01; 血压高升的原因 写脚本的时候&#xff0c;智能提示有哪些函数可以使用&#xff0c;是非常棒的一件事情&#xff0c;有助于游戏开发者编写和检查自己的脚本代码。 但是&#xff01; 我想输入…