WPF中如何使用区域导航

1.创建一个Prism框架的项目并设计好数据源

User如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WPF练习17区域导航.Models
{public class User{public int UserId { get; set; }public string UserName { get; set; }public string UserPwd { get; set; }}
}

UserData如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WPF练习17区域导航.Models
{public static class UserData{public static List<User> Users = new List<User>() {new User(){ UserId=1,UserName="张三1",UserPwd="123456"},new User(){ UserId=2,UserName="张三2",UserPwd="123456"}};}
}

2.设计好MainWindow.XAML页面 并创建四个UserControl的导航页面以及相应的ViewModel然后将视图注册进Ioc容器

MainWindow.XAML如下:

<Window x:Class="WPF练习17区域导航.Views.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:prism="http://prismlibrary.com/"prism:ViewModelLocator.AutoWireViewModel="True"Title="{Binding Title}"Height="350"Width="525"WindowStartupLocation="CenterScreen"><Grid><Grid.RowDefinitions><RowDefinition Height="60" /><RowDefinition /></Grid.RowDefinitions><Grid Background="Blue"><WrapPanel VerticalAlignment="Center"><TextBlock VerticalAlignment="Center"FontSize="30"Foreground="White"Text="XXX管理系统" /><Button Width="50"Margin="10,0,0,0"Command="{Binding BackCommand}"Content="后退" /><Button Width="50"Margin="10,0,0,0"Command="{Binding ForwardCommand}"Content="前进" /></WrapPanel></Grid><Grid Grid.Row="1"><Grid.ColumnDefinitions><ColumnDefinition Width="160" /><ColumnDefinition /></Grid.ColumnDefinitions><StackPanel Background="Green"><Button Height="30"Margin="0,10,0,0"Command="{Binding TogglePage}"CommandParameter="{Binding RelativeSource={RelativeSource Self}}"Content="PageA" /><Button Height="30"Margin="0,10,0,0"Command="{Binding TogglePage}"CommandParameter="{Binding RelativeSource={RelativeSource Self}}"Content="PageB" /><Button Height="30"Margin="0,10,0,0"Command="{Binding TogglePage}"CommandParameter="{Binding RelativeSource={RelativeSource Self}}"Content="PageC" /></StackPanel><Border Grid.Column="1"Padding="10"BorderBrush="Red"BorderThickness="2"><ContentControl prism:RegionManager.RegionName="ContentRegion" /></Border></Grid></Grid>
</Window>

创建四个UserControl的导航页面:

将视图注册进Ioc容器:

3.四个页面设计好以后 写好MainWIndow对应的ViewModel代码

PageA如下:

<UserControl x:Class="WPF练习17区域导航.Views.Pages.PageA"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPF练习17区域导航.Views.Pages"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><Grid.RowDefinitions><RowDefinition Height="50" /><RowDefinition /><RowDefinition Height="30" /></Grid.RowDefinitions><StackPanel VerticalAlignment="Center"><TextBlock Text="查询条件区域" /></StackPanel><DataGrid Grid.Row="1"AutoGenerateColumns="False"IsReadOnly="True"ItemsSource="{Binding Users}"><DataGrid.Columns><DataGridTextColumn Width="*"Binding="{Binding UserId}"Header="编号" /><DataGridTextColumn Width="*"Binding="{Binding UserName}"Header="账号" /><DataGridTextColumn Width="*"Binding="{Binding UserPwd}"Header="密码" /><DataGridTemplateColumn Width="3*"Header="操作"><DataGridTemplateColumn.CellTemplate><DataTemplate><WrapPanel><Button Width="50"Margin="5,0,0,0"Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"CommandParameter="{Binding UserId}"Content="编辑" /><Button Width="50"Margin="5,0,0,0"Content="删除" /><Button Width="70"Margin="5,0,0,0"Content="分配权限" /><Button Width="50"Margin="5,0,0,0"Content="详情" /></WrapPanel></DataTemplate></DataGridTemplateColumn.CellTemplate></DataGridTemplateColumn></DataGrid.Columns></DataGrid><StackPanel Grid.Row="2"VerticalAlignment="Center"><TextBlock Text="分页区域" /></StackPanel></Grid>
</UserControl>

PageAViewModel如下:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using WPF练习17区域导航.Models;namespace WPF练习17区域导航.ViewModels.Pages
{public class PageAViewModel: BindableBase, INavigationAware, IConfirmNavigationRequest{private readonly IRegionManager regionManager;public PageAViewModel(IRegionManager regionManager){this.regionManager = regionManager;}private List<User> users = UserData.Users;public List<User> Users{get { return users; }set { SetProperty(ref users, value); }}public DelegateCommand<object> EditCommand{get{return new DelegateCommand<object>((obj) =>{int userId = (int)obj;// 导航到编辑页面,并且需要向编辑页面传递参数UserIdNavigationParameters parameters = new NavigationParameters{{ "uid", userId }};// 通过NavigationParameters对象向导航传递参数this.regionManager.Regions["ContentRegion"].RequestNavigate("PageAEdit", parameters);});}}#region INavigationAwre// 第一次进入页面不会执行,第2次之后都会进入。public bool IsNavigationTarget(NavigationContext navigationContext){//MessageBox.Show("PageA IsNavigationTarget!");return false;}// 站在当前页面的角度:OnNavigatedFrom离开当前页面public void OnNavigatedFrom(NavigationContext navigationContext){//MessageBox.Show("离开PageA!");}// 站在当前页面的角度:OnNavigatedTo到当前页面public void OnNavigatedTo(NavigationContext navigationContext){//MessageBox.Show("到PageA!");}#endregion#region IConfirmNavigationRequest// 时机:如果从PageA跳转到PageAEdit页面,需要进行导航确认,应该把导航确认的业务逻辑流写到来源页面。// 导航时,确认是否允许导航动作。// navigationContext导航上下文对象。// continuationCallback回调函数。public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback){if (navigationContext.Uri.ToString() == "PageAEdit"){MessageBoxResult mbr = MessageBox.Show("是否允许进入PageAEdit页面?", "询问", MessageBoxButton.YesNo, MessageBoxImage.Question);bool isAllow = false;if (mbr == MessageBoxResult.Yes){isAllow = true;}continuationCallback(isAllow);}else{continuationCallback(true);}}#endregion}
}

在WPF中使用Prism框架时,INavigationAwareIConfirmNavigationRequest是两个重要的接口,它们允许视图或视图模型参与导航过程,提供了对导航行为的细粒度控制。

INavigationAware

INavigationAware接口包含三个方法,用于在导航过程中与视图或视图模型进行交互:

  • bool IsNavigationTarget(NavigationContext navigationContext):当导航到视图或视图模型时,该方法被调用,以确定当前实例是否可以处理导航请求。通常返回true,表示当前视图可以处理导航
  • void OnNavigatedTo(NavigationContext navigationContext):当视图被导航到的时候,该方法被调用。可以用来初始化视图或处理传入的参数。
  • void OnNavigatedFrom(NavigationContext navigationContext):当视图被导航离开时,该方法被调用。可以用来保存状态或清理资源。

IConfirmNavigationRequest

IConfirmNavigationRequest接口继承自INavigationAware,并添加了一个方法ConfirmNavigationRequest,用于在导航发生前与用户交互,以确认或取消导航:

  • void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback):该方法提供了两个参数,一个是当前导航上下文,另一个是一个回调方法。在调用该方法时,可以显示一个确认对话框,根据用户的选择调用回调方法以决定是否继续导航。例如,如果用户选择取消,则导航将被取消。

PageAEdit.XAML如下:

<UserControl x:Class="WPF练习17区域导航.Views.Pages.PageAEdit"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPF练习17区域导航.Views.Pages"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid HorizontalAlignment="Center"VerticalAlignment="Center"><StackPanel><WrapPanel Margin="0,10,0,0"><TextBlock Text="账号:" /><TextBox Width="150"Text="{Binding CurrentEditUser.UserName}" /></WrapPanel><WrapPanel Margin="0,10,0,0"><TextBlock Text="密码:" /><TextBox Width="150"Text="{Binding CurrentEditUser.UserPwd}" /></WrapPanel><WrapPanel Margin="0,10,0,0"><Button Width="50"Content="保存" /></WrapPanel><WrapPanel Margin="0,10,0,0"><Button Width="160"Command="{Binding GoOtherEditCommand}"CommandParameter="2"Content="详情页面跳转到其他详情" /></WrapPanel></StackPanel></Grid>
</UserControl>

PageAEditViewModel如下:

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WPF练习17区域导航.Models;namespace WPF练习17区域导航.ViewModels.Pages
{// 在PageAEdit页面接收到UserId才能处理下一步的逻辑。// 一个跳转目标(PageAEdit页面)要想接收传递过来的参数:必须实现INavigationAwarepublic class PageAEditViewModel : BindableBase, INavigationAware{private readonly IRegionManager regionManager;public PageAEditViewModel(IRegionManager regionManager){this.regionManager = regionManager;}private User currentEditUser;public User CurrentEditUser{get { return currentEditUser; }set { SetProperty(ref currentEditUser, value); }}#region INavigationWare// IsNavigationTarget()第一次进入页面不会执行,第2次之后才会进入。// 通过调试,会发现IsNavigationTarget()方法返回true或false达到效果是一样。但是性能不一样。// 如果返回true,说明不会重新创建视图实例,不会重新创建导航上下文,即:IsNavigationTarget()方法中使用的视图实例及上下文会在OnNavigatedTo()方法中共用。// 如果返回false,说明会重新创建视图实例,会重新创建导航上下文,即:IsNavigationTarget()方法中使用的视图实例及上下文和OnNavigatedTo()方法中使用的视图实例及上下文不是同一个实例。/*IsNavigationTarget()方法用来控制视图或者视图模型实例在导航时是否被重用。当你尝试导航到一个新的视图的时候,Prism会检查当前活动的视图或者视图模型的实例,并调用他们的IsNavigationTarget方法,以决定是否可以重用这个实例。如果返回true,Prism框架将不会创建新的视图或者视图模型实例,而是重用当前的实例。这种方式非常适用于那些数据和状态不需要每次都重新加载的视图,可以提高应用程序的响应速度和资源利用率。*/public bool IsNavigationTarget(NavigationContext navigationContext){Console.WriteLine(navigationContext);//MessageBox.Show("PageAEdit IsNavigationTarget!");return true;}// 站在当前页面的角度:OnNavigatedFrom离开当前页面public void OnNavigatedFrom(NavigationContext navigationContext){//MessageBox.Show("离开PageAEdit!");}// 站在当前页面的角度:OnNavigatedTo到当前页面// 拿参数的时机:在进入当前页面时,拿传递的参数最合理。// 如何拿参数?NavigationContext导航的上下文,拿到上下文就可以拿Uri, Parameters, NavigationService 操作API(导航服务)public void OnNavigatedTo(NavigationContext navigationContext){object obj = navigationContext.Parameters["uid"]; // 取传值方式1int uid1 = (int)obj;int uid2 = navigationContext.Parameters.GetValue<int>("uid");//取传值方式2// AsQueryable()转换成IQueryable<T>,由于IQueryable<T>继承IEnumerable<T>接口,从而可以调用LINQ扩展方法。CurrentEditUser = UserData.Users.AsQueryable().Where(u => u.UserId == uid1).FirstOrDefault();//MessageBox.Show("到PageAEdit!");}#endregionpublic DelegateCommand<object> GoOtherEditCommand{get{return new DelegateCommand<object>(obj =>{int uid = Convert.ToInt32(obj);NavigationParameters parameters = new NavigationParameters(){{"uid",uid}};this.regionManager.RequestNavigate("ContentRegion", "PageAEdit", parameters);});}}}
}

PageB如下:

<UserControl x:Class="WPF练习17区域导航.Views.Pages.PageB"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPF练习17区域导航.Views.Pages"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><TextBlock Text="PageB" /></Grid>
</UserControl>

PageBViewModel如下:

using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace 区域导航.ViewModels.Pages
{public class PageBViewModel : BindableBase{}
}

PageC如下:

<UserControl x:Class="WPF练习17区域导航.Views.Pages.PageC"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPF练习17区域导航.Views.Pages"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><TextBlock Text="PageC" /></Grid>
</UserControl>

PageCViewModel如下:

using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace WPF练习17区域导航.ViewModels.Pages
{public class PageCViewModel : BindableBase{}
}

4.最后写好MainWindowViewModel代码

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System.Windows.Controls;namespace WPF练习17区域导航.ViewModels
{public class MainWindowViewModel : BindableBase{// 导航日志服务,主要负责提供导航日志的管理,如:添加导航日志,根据导航日志可以前进,后退等等。// 添加导航日志的时机,应该在导航跳转成功后,添加导航日志。private IRegionNavigationJournal journal;private readonly IRegionManager regionManager;// 使用依赖注入的把区域管理服务注入当前的VM。public MainWindowViewModel(IRegionManager regionManager, IRegionNavigationJournal journal){this.regionManager = regionManager;this.journal = journal;}private string _title = "Prism Application";public string Title{get { return _title; }set { SetProperty(ref _title, value); }}public DelegateCommand<object> TogglePage{get{return new DelegateCommand<object>(obj =>{Button button = obj as Button;// 导航跳转// 前提:需要把视图先扔到Ioc容器// 1。拿区域管理器(其实是区域给VM提供的一种服务而异)// 2。从区域管理器中拿某个区域// 3。调用区域的API(导航服务)// 参数1:导航的目标视图名称。参数2:导航后(有可能成功,也有可能失败)的回调函数。参数3:导航参数。this.regionManager.Regions["ContentRegion"].RequestNavigate(button.Content.ToString(),NavigationCallback,new NavigationParameters());});}}private void NavigationCallback(NavigationResult navigationResult){// 导航成功//if(navigationResult.Result==true)//if((bool)navigationResult.Result)if (navigationResult.Result.Value == true){// 添加导航日志的时机,应该在导航跳转成功后,添加导航日志。// navigationResult.Context先拿导航上下文。// NavigationService导航服务// Journal日志journal = navigationResult.Context.NavigationService.Journal;}}public DelegateCommand ForwardCommand{get{return new DelegateCommand(() =>{if (journal != null && journal.CanGoForward){journal.GoForward();}});}}public DelegateCommand BackCommand{get{return new DelegateCommand(() =>{if (journal != null && journal.CanGoBack){journal.GoBack();}});}}}
}

5.效果如下:

 

 

 

 

 

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

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

相关文章

基于Cocos Creator开发的打砖块游戏

一、简介 Cocos简而言之就是一个开发工具&#xff0c;详见官方网站TypeScript简而言之就是开发语言&#xff0c;是JavaScript的一个超集详解官网 今天我们就来学习如何写一个打砖块的游戏&#xff0c;很简单的一个入门级小游戏。 二、实现过程 2.1 布局部分 首先来一个整体…

【数据结构】线性表——栈与队列

写在前面 栈和队列的关系与链表和顺序表的关系差不多&#xff0c;不存在谁替代谁&#xff0c;只有双剑合璧才能破敌万千~~&#x1f60e;&#x1f60e; 文章目录 写在前面一、栈1.1栈的概念及结构1.2、栈的实现1.2.1、栈的结构体定义1.2.2、栈的初始化栈1.2.3、入栈1.2.4、出栈…

Rust编程与项目实战-特质(Trait)

【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 特质&#xff08;Trait&#xff09;是Rust中的概念&#xff0c;类似于其他语言中的接…

运维之systemd 服务(Systemd Service of Operations and Maintenance)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

Vue — 组件化开发

组件化开发&#xff1a;一个页面可以拆分成一个个组件&#xff1b;每个组件都有自己独立的结构、样式、行为 组件分类&#xff1a;普通组件、根组件 其中根组件包裹着所有普通小组件 普通组件的注册使用&#xff1b;有两种注册方式 局部注册全局注册 局部注册 目标&#xff…

【软考】系统架构设计师-计算机系统基础(2):操作系统

1、操作系统基础 OS的5个核心功能&#xff1a;进程管理、存储管理、设备管理、文件管理、作业管理 OS的3个作用&#xff1a;管理运行的程序和分配各种软硬件资源&#xff1b;提供友善的人机界面&#xff1b;为程序应用的开发和运行提供高效的平台 OS的4个特征&#xff1a;并…

Android ANR分析总结

1、ANR介绍 ANR&#xff08;Application Not Responding&#xff09;指的是应用程序无响应&#xff0c;当Android应用程序在主线程上执行长时间运行的操作或阻塞I/O操作时发生。这可能导致应用程序界面冻结或无法响应用户输入。 1、Service ANR&#xff1a;前台20s&#xff0…

WebRTC视频 01 - 视频采集整体架构

一、前言&#xff1a; 我们从1对1通信说起&#xff0c;假如有一天&#xff0c;你和你情敌使用X信进行1v1通信&#xff0c;想象一下画面是不是一个大画面中有一个小画面&#xff1f;这在布局中就叫做PIP&#xff08;picture in picture&#xff09;&#xff1b;这个随手一点&am…

Jenkins应用详解(Detailed Explanation of Jenkins Application)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【Python】计算机视觉应用:OpenCV库图像处理入门

计算机视觉应用&#xff1a;OpenCV库图像处理入门 在当今的数字化时代&#xff0c;计算机视觉&#xff08;Computer Vision&#xff09;已经渗透到各行各业&#xff0c;比如自动驾驶、智能监控、医疗影像分析等。而 Python 的 OpenCV 库&#xff08;Open Source Computer Visi…

ctfshow-web入门-反序列化(web260-web264)

目录 1、web260 2、web261 3、web262 4、web263 5、web264 1、web260 要求传入的内容序列化后包含指定内容即可&#xff0c;在 PHP 序列化中&#xff0c;如果键名或值包含 ctfshow_i_love_36D&#xff0c;那么整个序列化结果也会包含这个字符串。 payload&#xff1a; ?…

Python 爬虫运行状态监控:进度、错误与完成情况

Python 爬虫运行状态监控&#xff1a;进度、错误与完成情况 在进行大规模数据爬取时&#xff0c;监控爬虫的运行状态至关重要。通过实时监控&#xff0c;可以了解爬虫的工作进度、出现的错误以及任务完成情况。这样可以及时发现并解决问题&#xff0c;确保数据抓取任务顺利进行…

Flutter错误: uses-sdk:minSdkVersion 16 cannot be smaller than version 21 declared

前言 今天要做蓝牙通信的功能&#xff0c;我使用了flutter_reactive_ble这个库&#xff0c;但是在运行的时候发现一下错误 Launching lib/main.dart on AQM AL10 in debug mode... /Users/macbook/Desktop/test/flutter/my_app/android/app/src/debug/AndroidManifest.xml Err…

除了易我数据恢复,这10个数据恢复软件也能点亮数据找回的希望之光。

易我数据恢复工具具有广泛的系统兼容性&#xff0c;并且里面功能丰富&#xff0c;操作简单&#xff0c;能够完成多种数据恢复操作&#xff0c;是一款比较专业的数据恢复软件。如果大家在为数据丢失而烦恼的话&#xff0c;我可以推荐几款好用的数据恢复软件给大家。 1、福昕数据…

Vue Cli 脚手架目录文件介绍

小试牛刀 //vetur高亮; vuetab 快速生成 <template><div class"box">我是个盒子<button click"fn">按钮</button></div> </template><script> export default {methods:{fn(){alert("Hello Vue")}} …

在公司中,如何表现出自己的高情商,学会这三句话就可以了

在职场中&#xff0c;高情商的重要性不言而喻。它能帮助你更好地处理人际关系&#xff0c;提升团队协作效率&#xff0c;还能让你在职场上获得更多的机会。 在职场中&#xff0c;适时地给予同事、上级和下属赞美、感谢和鼓励&#xff0c;能够拉近彼此的距离&#xff0c;增强团…

cache(五)Write-through,Write-back,Write-allocate,No-write-allocate

这张图总结了缓存系统中写操作策略的不同方法&#xff0c;主要讨论了在**写命中&#xff08;write-hit&#xff09;和写未命中&#xff08;write-miss&#xff09;**情况下应该采取的操作策略。 1. 多个数据副本的存在 缓存系统通常有多个级别&#xff0c;例如 L1 缓存、L2 缓…

商品规格递归拼接

创建实体类 Data public class Shopping {private String name;private List<String> children; } 测试 public static void main(String[] args) {ArrayList<Shopping> shoppings new ArrayList<>();Shopping shopping new Shopping();shopping.setName…

大模型基础: 从零开始训练一个最小化的Transformer聊天机器人

这里将介绍如何从零开始&#xff0c;使用Transformer模型训练一个最小化的聊天机器人。该流程将尽量简化&#xff0c;不依赖预训练模型&#xff0c;并手动实现关键步骤&#xff0c;确保每一步都容易理解。 1. 环境准备 首先&#xff0c;确保安装了必要的Python库。我们只需要基…

推荐一款3D建模软件:Agisoft Metashape Pro

Agisoft Metashape Pro是一款强大的多视点三维建模设计辅助软件&#xff0c;Agisoft Metashape是一款独立的软件产品&#xff0c;可对数字图像进行摄影测量处理&#xff0c;并生成3D空间数据&#xff0c;用于GIS应用&#xff0c;文化遗产文档和视觉效果制作&#xff0c;以及间接…