Wpf 使用 Prism 实战开发Day04

一.菜单导航实现


1.首先创建出所有的页面(View)及对应的页面逻辑处理类(ViewModel)

  1.  IndexView(首页)-----------------IndexViewModel
  2. ToDoView(待办事项)------------ToDoViewModel
  3. MemoView(忘备录)--------------MemoViewModel
  4. SettingsView(设置)--------------SettingsViewModel

注意:创建View时,添加的是用户控件 

2. 在 MainView.xaml 添加内容展示区域 

通俗点理解就是,其他页面的内容需要有控件去展现出来给用户看。然后就用到一个ContentControl  控件来展现内容,并且也需要用到 Prism 框架里面的区域 (并且通过定义一个区域名称来定位到展现的位置)。我是这样理解的。首先这不是教程,是我学习的记录,如果错了,就错了。

  • 例如,在 ContentControl 中定义一个区域名称,并且使用 prism 注册这个区域
<ContentControl prism:RegionManager.RegionName=""/>

 建议:通过一个扩展类来管理定义的一些属性名称

例如:当前定义的区域名称,通过建立一个扩展类来进行管理

 public static class PrismManager{public static readonly string MainViewRegionName = "MainViewReion";}

  • 扩展类定义完成后,需要在使用到的 MainView 页面中,添加命名空间进行使用这个静态扩展类
xmlns:ext="clr-namespace:MyToDo.Extensions"
  1. xmlns: 是引入命名空间固定的写法
  2. ext 是自定义的名称
  3. = 号后面是扩展类所在的命名空间 

  • 最后,在 ContentControl 控件中去引用这个静态类定义的属性
 <ContentControl prism:RegionManager.RegionName="{x:Static ext:PrismManager.MainViewRegionName}"/>

x:Static 是引用静态类型的属性的固定前缀的写法 


 3.进行页面导航注册

  • 在App.xaml.cs中,把页面(View)和 业务处理类(ViewModel) 进行依赖关联并注册进导航容器中

  /// <summary>/// 依懒注入的方法/// </summary>/// <param name="containerRegistry"></param>protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();containerRegistry.RegisterForNavigation<MemoView, MemoViewModel>();containerRegistry.RegisterForNavigation<ToDoView, ToDoViewModel>();containerRegistry.RegisterForNavigation<SettingsView, SettingsViewModel>();}

 5. 接着在添加导航命令

  • 在MainViewModel.cs 中,添加导航命令。作用是用来驱动整个页面的导航
  • 接着,还需要添加 IRegionManager,通过在Prism 提供的IRegionManager.Regions 来找到应用程序所注册的导航区域名称(就是内容展现区域定义的名称)
  • 最后,通过.出来RequestNavigate 属性,取菜单传过来的命名空间做为导航的目标页面。
 public class MainViewModel: BindableBase{public MainViewModel(IRegionManager regionManager){NavigateCommand = new DelegateCommand<MenuBar>(Navigate);this.regionManager = regionManager;}/// <summary>
/// 导航方法
/// </summary>
/// <param name="bar">菜单</param>
private void Navigate(MenuBar bar)
{//命名空间为空,不进行导航if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace);
}/// <summary>/// 导航命令/// </summary>public DelegateCommand<MenuBar> NavigateCommand { get; private set; }}

6.实现上一步,下一步导航功能

通过添加导航日志 IRegionNavigationJournal 来实现,上一步,下一步的导航功能

  • 修改导航方法,添加导航成功回调函数
 /// <summary>/// 导航方法/// </summary>/// <param name="bar">菜单</param>private void Navigate(MenuBar bar){//命名空间为空,不进行导航if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>{}); }
  • 添加一个区域导航日志 IRegionNavigationJournal,用来记录导航的结果 ,并且在回调函数中实例化导航日志
 public class MainViewModel: BindableBase{public MainViewModel(IRegionManager regionManager){NavigateCommand = new DelegateCommand<MenuBar>(Navigate);this.regionManager = regionManager;}/// <summary>/// 导航方法/// </summary>/// <param name="bar">菜单</param>private void Navigate(MenuBar bar){//命名空间为空,不进行导航if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>{journal=back.Context.NavigationService.Journal;      }); }/// <summary>/// 导航命令/// </summary>public DelegateCommand<MenuBar> NavigateCommand { get; private set; }private readonly IRegionManager regionManager;/// <summary>/// 导航日志/// </summary>private IRegionNavigationJournal journal;}
  • 接着,再添加两个命令,绑定前端按钮点击上一步或下一步按钮,并且进行初始化
 public class MainViewModel: BindableBase{public MainViewModel(IRegionManager regionManager){NavigateCommand = new DelegateCommand<MenuBar>(Navigate);this.regionManager = regionManager;GoBackCommand = new DelegateCommand(() =>{if(journal!=null && journal.CanGoBack) journal.GoBack();});GoForwardCommand = new DelegateCommand(() =>{if (journal != null && journal.CanGoForward) journal.GoForward();});}/// <summary>/// 导航方法/// </summary>/// <param name="bar">菜单</param>private void Navigate(MenuBar bar){//命名空间为空,不进行导航if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>{journal=back.Context.NavigationService.Journal;      }); }/// <summary>/// 导航命令/// </summary>public DelegateCommand<MenuBar> NavigateCommand { get; private set; }/// <summary>/// 下一步/// </summary>public DelegateCommand GoBackCommand { get; private set; }/// <summary>/// 上一步/// </summary>public DelegateCommand GoForwardCommand { get; private set; }private readonly IRegionManager regionManager;/// <summary>/// 导航日志/// </summary>private IRegionNavigationJournal journal;}
  • 最后,在MainView页面的上一步和下一步按钮绑定ViewMode 写好的命令

7.在ListBox中,添加事件行为,作用是,当用户选中子项内容的时候,触发导航的行为。

  • 需要添加行为的命名空间

引入行为命名空间 xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

  •  接着在ListBox 中,添加选中行为事件,来触发导航

<i:Interaction.Triggers><i:EventTrigger EventName="SelectionChanged"><i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{Binding ElementName=menuBar,Path=SelectedItem}" /></i:EventTrigger>
</i:Interaction.Triggers>
  •  Interaction.Triggers  行为触发器
  • EventTrigger 触发的事件
  • EventName 触发事件的名称,这个事件命名,一定是ListBox存在的事件名称,不是随便起的名称
  • InvokeCommandAction 绑定后台要触发的导航命令
  • CommandParameter 绑定当前选中项。例如。这是传过去后台命令的参数

例如,上面是通过选中ListBox Item的子项来触发导航命令

8.优化点击菜单子项的同时关闭左侧菜单

  • 只需要绑定ListBox 的SelectionChanged 选择事件,点击的时候让左侧边框收起即可

//菜单选择事件
menuBar.SelectionChanged += (s, e) =>
{drawerHost.IsLeftDrawerOpen = false;
};
  • menuBar  是ListBox 定义的名称
  • drawerHost 是左侧弹框定义的名称

二.源码 

  • MainView.xaml 

<Window x:Class="MyToDo.Views.MainView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:ext="clr-namespace:MyToDo.Extensions"xmlns:local="clr-namespace:MyToDo"xmlns:prism="http://prismlibrary.com/"xmlns:i="http://schemas.microsoft.com/xaml/behaviors"prism:ViewModelLocator.AutoWireViewModel="True"WindowStyle="None" WindowStartupLocation="CenterScreen" AllowsTransparency="True"Style="{StaticResource MaterialDesignWindow}"TextElement.Foreground="{DynamicResource MaterialDesignBody}"Background="{DynamicResource MaterialDesignPaper}"TextElement.FontWeight="Medium"TextElement.FontSize="14"FontFamily="{materialDesign:MaterialDesignFont}"mc:Ignorable="d"xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"Title="MainWindow" Height="768" Width="1280"><materialDesign:DialogHost DialogTheme="Inherit"Identifier="RootDialog"SnackbarMessageQueue="{Binding ElementName=MainSnackbar, Path=MessageQueue}"><materialDesign:DrawerHost x:Name="drawerHost" IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}"><!--左边菜单--><materialDesign:DrawerHost.LeftDrawerContent><DockPanel MinWidth="220" ><!--头像--><StackPanel DockPanel.Dock="Top" Margin="0,20"><Image Source="/Images/user.jpg" Width="50" Height="50"><Image.Clip><EllipseGeometry Center="25,25" RadiusX="25" RadiusY="25" /></Image.Clip></Image><TextBlock Text="WPF gg" Margin="0,10" HorizontalAlignment="Center" /></StackPanel><!--列表--><ListBox  x:Name="menuBar" ItemContainerStyle="{StaticResource MyListBoxItemStyle}" ItemsSource="{Binding MenuBars}"><i:Interaction.Triggers><i:EventTrigger EventName="SelectionChanged"><i:InvokeCommandAction Command="{Binding NavigateCommand}" CommandParameter="{Binding ElementName=menuBar,Path=SelectedItem}" /></i:EventTrigger></i:Interaction.Triggers><ListBox.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal" Background="Transparent"><materialDesign:PackIcon Kind="{Binding Icon}" Margin="15,0" /><TextBlock Text="{Binding Title}" Margin="10,0"/></StackPanel></DataTemplate></ListBox.ItemTemplate></ListBox></DockPanel></materialDesign:DrawerHost.LeftDrawerContent><DockPanel ><!--导航条色块--><materialDesign:ColorZone Padding="16" x:Name="ColorZone"materialDesign:ElevationAssist.Elevation="Dp4"DockPanel.Dock="Top"Mode="PrimaryMid"><DockPanel LastChildFill="False"><!--上左边内容--><StackPanel Orientation="Horizontal"><ToggleButton x:Name="MenuToggleButton"AutomationProperties.Name="HamburgerToggleButton"IsChecked="False"Style="{StaticResource MaterialDesignHamburgerToggleButton}" /><Button Margin="24,0,0,0"materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"Command="{Binding GoForwardCommand}"Content="{materialDesign:PackIcon Kind=ArrowLeft,Size=24}"Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"Style="{StaticResource MaterialDesignToolButton}"ToolTip="Previous Item" /><Button Margin="16,0,0,0"materialDesign:RippleAssist.Feedback="{Binding RelativeSource={RelativeSource Self}, Path=Foreground, Converter={StaticResource BrushRoundConverter}}"Command="{Binding GoBackCommand}"Content="{materialDesign:PackIcon Kind=ArrowRight,Size=24}"Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"Style="{StaticResource MaterialDesignToolButton}"ToolTip="Next Item" /><TextBlock Margin="16,0,0,0"HorizontalAlignment="Center"VerticalAlignment="Center"AutomationProperties.Name="Material Design In XAML Toolkit"FontSize="22"Text="笔记本" /></StackPanel><!--上右边图标--><StackPanel DockPanel.Dock="Right" Orientation="Horizontal"><Image Source="/Images/user.jpg" Width="25" Height="25"><Image.Clip><EllipseGeometry Center="12.5,12.5" RadiusX="12.5" RadiusY="12.5" /></Image.Clip></Image><Button x:Name="btnMin" Style="{StaticResource MaterialDesignFlatMidBgButton}"><materialDesign:PackIcon Kind="MoveResizeVariant" /></Button><Button x:Name="btnMax" Style="{StaticResource MaterialDesignFlatMidBgButton}"><materialDesign:PackIcon Kind="CardMultipleOutline" /></Button><Button x:Name="btnClose" Style="{StaticResource MaterialDesignFlatMidBgButton}" Cursor="Hand"><materialDesign:PackIcon Kind="WindowClose" /></Button></StackPanel></DockPanel></materialDesign:ColorZone><!--内容展现区域--><ContentControl prism:RegionManager.RegionName="{x:Static ext:PrismManager.MainViewRegionName}"/></DockPanel></materialDesign:DrawerHost></materialDesign:DialogHost>
</Window>
  •  MainView.xaml.cs

/// <summary>
/// MainView.xaml 的交互逻辑
/// </summary>
public partial class MainView : Window
{public MainView(){InitializeComponent();//最小化btnMin.Click += (s, e) =>{this.WindowState = WindowState.Minimized;//窗口设置最小};//最大化btnMax.Click += (s, e) =>{//判断窗口是否是最小化状态if (this.WindowState == WindowState.Maximized){this.WindowState = WindowState.Normal; //改成正常状态}else{this.WindowState = WindowState.Maximized;//最大化}};//关闭btnClose.Click += (s, e) =>{this.Close();};//鼠标拖动事件ColorZone.MouseMove += (s, e) =>{//如果鼠标在拖动if (e.LeftButton == MouseButtonState.Pressed){this.DragMove();//让窗口移动}};//导航栏双击事件ColorZone.MouseDoubleClick += (s, e) =>{//双击时,如果是窗口是正常形态,就变成最大化if (this.WindowState == WindowState.Normal){this.WindowState = WindowState.Maximized;}else{this.WindowState = WindowState.Normal;//否则就变成正常的形态}};//菜单选择事件menuBar.SelectionChanged += (s, e) =>{drawerHost.IsLeftDrawerOpen = false;};}
}
  • MainViewModel

public class MainViewModel: BindableBase
{public MainViewModel(IRegionManager regionManager){MenuBars=new ObservableCollection<MenuBar>();CreateMenuBar();NavigateCommand = new DelegateCommand<MenuBar>(Navigate);this.regionManager = regionManager;GoBackCommand = new DelegateCommand(() =>{if(journal!=null && journal.CanGoBack) journal.GoBack();});GoForwardCommand = new DelegateCommand(() =>{if (journal != null && journal.CanGoForward) journal.GoForward();});}/// <summary>/// 导航方法/// </summary>/// <param name="bar">菜单</param>private void Navigate(MenuBar bar){//命名空间为空,不进行导航if (bar == null || string.IsNullOrEmpty(bar.NameSpace)) return;regionManager.Regions[PrismManager.MainViewRegionName].RequestNavigate(bar.NameSpace, back =>{journal=back.Context.NavigationService.Journal;      }); }/// <summary>/// 导航命令/// </summary>public DelegateCommand<MenuBar> NavigateCommand { get; private set; }/// <summary>/// 下一步/// </summary>public DelegateCommand GoBackCommand { get; private set; }/// <summary>/// 上一步/// </summary>public DelegateCommand GoForwardCommand { get; private set; }private ObservableCollection<MenuBar> menuBars;private readonly IRegionManager regionManager;/// <summary>/// 导航日志/// </summary>private IRegionNavigationJournal journal;public ObservableCollection<MenuBar> MenuBars{get { return menuBars; }set { menuBars = value; RaisePropertyChanged(); }}void CreateMenuBar(){MenuBars.Add(new MenuBar() { Icon="Home",Title="首页",NameSpace="IndexView"});MenuBars.Add(new MenuBar() { Icon = "NotebookCheckOutline", Title = "待办事项", NameSpace = "ToDoView" });MenuBars.Add(new MenuBar() { Icon = "NotebookPlusOutline", Title = "忘备录", NameSpace = "MemoView" });MenuBars.Add(new MenuBar() { Icon = "Cog", Title = "设置", NameSpace = "SettingsView" });}
}
  • App.xaml.cs
 public partial class App : PrismApplication{/// <summary>/// 创建启动页面/// </summary>/// <returns></returns>protected override Window CreateShell(){return Container.Resolve<MainView>();}/// <summary>/// 依懒注入的方法/// </summary>/// <param name="containerRegistry"></param>protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterForNavigation<IndexView, IndexViewModel>();containerRegistry.RegisterForNavigation<MemoView, MemoViewModel>();containerRegistry.RegisterForNavigation<ToDoView, ToDoViewModel>();containerRegistry.RegisterForNavigation<SettingsView, SettingsViewModel>();}}

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

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

相关文章

使用Java AOP实现面向切面编程

简介 面向切面编程&#xff08;AOP&#xff09;是一种编程思想&#xff0c;它将程序中的关注点分离&#xff0c;使得开发人员可以专注于核心业务逻辑而不必过多关注横切关注点。Java中的AOP可以通过使用AspectJ等框架来实现&#xff0c;本文将介绍如何使用Java AOP实现切面编程…

计算机毕设 基于大数据的服务器数据分析与可视化系统 -python 可视化 大数据

文章目录 0 前言1 课题背景2 实现效果3 数据收集分析过程**总体框架图****kafka 创建日志主题****flume 收集日志写到 kafka****python 读取 kafka 实时处理****数据分析可视化** 4 Flask框架5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&a…

地址的层次性

地址的层次性 当地址总数并不是很多的情况下&#xff0c;有了唯一地址就可以定位相互通信的主体。然而当地址的总数越来越多时&#xff0c;如何高效地从中找出通信的目标地址将成为一个重要的问题。为此人们发现地址除了具有唯一性还需要具有层次性。其实&#xff0c;在使用电…

Elasticsearch:RAG vs Fine-tunning (大语言模型微调)

如果你对 RAG 还不是很熟悉的话&#xff0c;请阅读之前的文章 “Elasticsearch&#xff1a;什么是检索增强生成 - RAG&#xff1f;”。你可以阅读文章 “Elasticsearch&#xff1a;在你的数据上训练大型语言模型 (LLM)” 来了解更多关于如何训练你的模型。在今天的文章中&#…

MFC 基础篇(一)

目录 一.SDK编程 二.为什么要学MFC&#xff1f; 三.MFC能做什么&#xff1f; 四.MFC开发环境搭建 五.MFC项目创建 六.消息映射机制 一.SDK编程 Application Programming Interface 应用程序编程接口。 Software Development Kit 软件开发工具包&#xff0c;一般会包括A…

【LeetCode】每日一题 2023_11_6 最大单词长度乘积

文章目录 刷题前唠嗑题目&#xff1a;最大单词长度乘积题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;最大单词长度乘积 题目链接&#xff1a;318. 最大单词长度乘积 题目描述 代码与解题思路…

飞书开发学习笔记(二)-云文档简单开发练习

飞书开发学习笔记(二)-云文档简单开发练习 一.云文档飞书开发环境API 首先还是进入开放平台 飞书开放平台&#xff1a;https://open.feishu.cn/app?langzh-CN 云文档相关API都在“云文档”目录中&#xff0c;之下又有"云空间",“文档”&#xff0c;“电子表格”&a…

java智能在线考试系统源码 基于SpringBoot+Vue开发

java智能在线考试系统源码 基于SpringBootVue开发 环境介绍 语言环境&#xff1a;Java: jdk1.8 数据库&#xff1a;Mysql: mysql5.7 应用服务器&#xff1a;Tomcat: tomcat8.5.31 开发工具&#xff1a;IDEA或eclipse 开发技术&#xff1a;SpringbootVue 项目简介&…

手拿5份offer,最高18k! 95后艺术生转行后台网优,这个火花有点大!

当艺术生碰上理工科&#xff0c;会有怎样的火花&#xff1f;在大众的刻板认知里&#xff0c;艺术和理工科就像两条很少重合的平行线&#xff0c;双方从业者在自己的行业下按部就班&#xff0c;规划未来。 来自东北长春的W同学却打破了常人的认知&#xff0c;身为美术老师的他却…

观察者模式——解决解耦的钥匙

● 观察者模式介绍 观察者模式是一个使用频率非常高的模式&#xff0c;它最常用的地方是GUI系统、订阅——发布系统。因为这个模式的一个重要作用就是解耦&#xff0c;将被观察者和观察者解耦&#xff0c;使得它们之间依赖性更小&#xff0c;甚至做到毫无依赖。以CUI系统来说&a…

Unisat的核心成员神秘失踪两个月后,CHAX横空出世

在这个快速变化的数字世界中&#xff0c;故事似乎总是在不断上演。最近&#xff0c;一则消息在加密货币社区中引起了轩然大波&#xff1a;Unisat的核心成员神秘失踪两个月后&#xff0c;CHAX横空出世&#xff0c;带来了一股新的风潮。 受够了BRC20-Swap多次难产&#xff0c;落地…

2023年11月5日网规考试备忘

早上题目回忆&#xff1a; pki体系 ipsec&#xff0c;交换安全&#xff08;流量抑制&#xff09; aohdlc bob metclaf —ethernet pon tcp三次握手 OSPF lsa&#xff1f;交换机组ospf配置问题&#xff0c;ping网关可通&#xff0c;AB不通 raid6 300G*8 网络利用率 停等协议10…

VUE多语言i18n配置

1、i18n官网 格式化 | Vue I18n 2、安装i18n 8---指版本号 // vue2必须安装8版本的i18n包&#xff0c;vue3必须安装9版本的i18n包。 npm i vue-i18n8 3、卸载i18n npm uninstall vue-i18n 4、安装 js-cookie npm install vue-cookies --save 5、代码 5.1 main.js /…

ActiveMQ、RabbitMQ、RocketMQ、Kafka介绍

一、消息中间件的使用场景 消息中间件的使用场景总结就是六个字&#xff1a;解耦、异步、削峰 1.解耦 如果我方系统A要与三方B系统进行数据对接&#xff0c;推送系统人员信息&#xff0c;通常我们会使用接口开发来进行。但是如果运维期间B系统进行了调整&#xff0c;或者推送过…

Java后端开发——JDBC组件

JDBC&#xff08;Java Database Connectivity&#xff09;是Java SE平台的一种标准API&#xff0c;它提供了一种标准的方法来访问关系型数据库&#xff0c;使得Java程序能够与各种不同的数据库进行交互&#xff0c;这篇文章我们来进行实验体验一下。 自定义JDBC连接工具类 1.编…

stm32整理(三)ADC

1 ADC简介 1.1 ADC 简介 12 位 ADC 是逐次趋近型模数转换器。它具有多达 19 个复用通道&#xff0c;可测量来自 16 个外部 源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续 采样模式下进行。ADC 的结果存储在一个左对齐或右对齐的 16 位…

6款优质办公软件,个个都是效率神器,可免费使用

今天给大家分享6款优质的办公软件&#xff0c;这些软件不仅功能强大&#xff0c;还可以免费使用&#xff0c;让你高效完成工作。 Todo清单——待办事项软件 Todo清单是一款强大的跨平台待办事项和时间管理软件。它可以帮助用户记录、跟踪和完成待办事项。通过创建清单&#xff…

异星工场入门笔记-02-一个重要地学习方法

编程学习地整个过程&#xff0c;最重要的工具就是电脑&#xff0c;其中有一个重点就是可以无成本的重复测试&#xff0c;这大大降低了难度&#xff0c;节约了时间。真正难以学习的不是技术本身&#xff0c;而是材料成本和时间成本&#xff0c;降低这两个因素平地起高楼根本不是…

【MySQL】MVCC机制(undo log,read view)

文章目录 前言一. 预备知识二. 模拟MVCC三. Read View四. RC与RR的本质区别结束语 前言 MVCC&#xff08;多版本并发控制&#xff09;是一种用来解决读-写冲突的无锁并发控制 MVCC为事务分配单向增长的事务ID&#xff0c;为每个修改保存一个版本&#xff0c;版本与事物ID相关联…

关闭 win10自动更新、关闭激活

做工控或者数据大屏、服务器之类的,都不想系统自动更新,不知不觉自动重启类。 激活过了一段时间,又要重新激活这些事情,所以需要手工去关闭这些服务。 一、关闭 win10自动更新 首先打开 服务,找到windows update: window +R 输入:Services.msc 停止windows update ,然…