WPF MVVM模式实现DataGrid编辑

news2024/11/27 21:38:39

本文是一个MVVM模式开发的基础教程,完全手写实现,未借助三方框架,适用于初学者

要实现DataGrid的编辑,步骤如下:

1、创建两个窗口,第一个窗口用于显示DataGrid,

布局如下:

这个界面上我们放置了一个DataGrid控件,并增加了三列,前面两列用于显示数据,最后一列用于编辑命令。

MainWindow.xaml

 1 <Window x:Class="WPFDataGridEditDemo.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WPFDataGridEditDemo"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="450" Width="800">
 9     <Grid>
10         <DataGrid x:Name="datagrid" ItemsSource="{Binding StudentCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False"
11           CanUserAddRows="False" VerticalScrollBarVisibility="Hidden" IsReadOnly="True" Margin="20">
12             <DataGrid.Columns>
13                 <DataGridTextColumn Header="学号" Width="60" Binding="{Binding ID}"/>
14                 <DataGridTextColumn Header="姓名" Width="*" Binding="{Binding Name}"/>
15                 <DataGridTemplateColumn Header="操作" Width="120">
16                     <DataGridTemplateColumn.CellTemplate>
17                         <DataTemplate>
18                             <StackPanel Orientation="Horizontal">
19                                 <TextBlock Margin="0,0,5,0">
20                                     <Hyperlink Command="{Binding EditCommand}" CommandParameter="{Binding ElementName=datagrid,Path=SelectedItem}">编辑</Hyperlink>
21                                 </TextBlock>
22                             </StackPanel>
23                         </DataTemplate>
24                     </DataGridTemplateColumn.CellTemplate>
25                 </DataGridTemplateColumn>
26             </DataGrid.Columns>
27         </DataGrid>
28     </Grid>
29 </Window>

2、创建一个编辑窗口,这个窗口用于编辑字段值

DataEditView.xaml

 1 <Window x:Class="WPFDataGridEditDemo.Views.DataEditView"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:WPFDataGridEditDemo.Views"
 7         mc:Ignorable="d"
 8         Title="DataEditView" Height="450" Width="800">
 9     <Grid>
10         <Border>
11             <Grid Background="Transparent">
12                 <TabControl BorderThickness="0" Margin="0,5">
13                     <TabItem Header="学生信息" FontSize="12">
14                         <Grid>
15                             <Grid.ColumnDefinitions>
16                                 <ColumnDefinition/>
17                                 <ColumnDefinition Width="1.6*"/>
18                             </Grid.ColumnDefinitions>
19                             <Grid>
20                                 <Grid.RowDefinitions>
21                                     <RowDefinition Height="40"/>
22                                     <RowDefinition/>
23                                 </Grid.RowDefinitions>
24 
25                                 <TextBlock Text="姓名" Margin="18,0" VerticalAlignment="Center"/>
26                             </Grid>
27                             <Grid Grid.Column="1">
28                                 <Grid.RowDefinitions>
29                                     <RowDefinition Height="40"/>
30                                     <RowDefinition/>
31                                 </Grid.RowDefinitions>
32 
33                                 <TextBox Grid.Row="0" Text="{Binding Name}" Height="23" VerticalContentAlignment="Center" Width="220"/>
34                                 <Button Grid.Row="6" Content="保存"  Width="88" Height="28" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10"
35                                 CommandParameter="{Binding .,RelativeSource={RelativeSource AncestorType=Window}}" Background="LightBlue" Command="{Binding SaveCommand}" />
36                             </Grid>
37                         </Grid>
38                     </TabItem>
39                 </TabControl>
40             </Grid>
41         </Border>
42     </Grid>
43 </Window>

3、定义一下MVVM中使用的命令对象CommandBase类

 1     public class CommandBase : ICommand
 2     {
 3         public event EventHandler CanExecuteChanged;
 4 
 5         public bool CanExecute(object parameter)
 6         {
 7             return true;
 8         }
 9 
10         public void Execute(object parameter)
11         {
12             DoExecute?.Invoke(parameter);
13         }
14 
15         public Action<object> DoExecute { get; set; }
16     }

4、创建一个用于DataGrid显示的数据模型Student,数据模型的字段名要跟DataGrid的列名绑定的属性名对应。

 1  public class Student : INotifyPropertyChanged
 2  {
 3      public event PropertyChangedEventHandler PropertyChanged;
 4 
 5      public void NotifyChanged([CallerMemberName] string propName = "")
 6      {
 7          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));//全局通知(给监听此属性的控件)
 8      }
 9 
10      private int id;
11      private string name;
12 
13      public int ID 
14      {
15          get => id; 
16          set
17          {
18              id = value;
19              NotifyChanged();
20          }
21      }
22 
23      public string Name
24      { 
25          get => name;
26          set
27          {
28              name = value;
29              NotifyChanged();
30          }
31      }
32 
33      private CommandBase editCommand;
34 
35      public CommandBase EditCommand
36      {
37          get
38          {
39              if (editCommand == null)
40              {
41                  editCommand = new CommandBase();
42                  editCommand.DoExecute = new Action<object>(obj => {
43                     //预留
44                  });
45              }
46              return editCommand;
47          }
48 
49      }

5、为界面创建ViewModel,ViewModel里增加一个用于显示到DataGrid的列表属性StudentCollection

 1 public class MainWindowViewModel : INotifyPropertyChanged
 2 {
 3     public event PropertyChangedEventHandler PropertyChanged;
 4 
 5     public void RaiseChanged([CallerMemberName] string propertyName = "")
 6     {
 7         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 8     }
 9 
10     private ObservableCollection<Student> studentCollection = new ObservableCollection<Student>();
11 
12     public ObservableCollection<Student> StudentCollection
13     {
14         get => this.studentCollection;
15         set
16         {
17             studentCollection = value;
18             this.RaiseChanged();
19         }
20     }
21 }

6、构造一个测试数据,并将ViewModel绑定到主窗口的DataContext上。

 1 public partial class MainWindow : Window
 2 {
 3     public MainWindow()
 4     {
 5         InitializeComponent();
 6 
 7         var mainviewmodel = new MainWindowViewModel();
 8 
 9         mainviewmodel.StudentCollection.Add(new Model.Student() { ID = 1, Name = "标签111111" });
10         mainviewmodel.StudentCollection.Add(new Model.Student() { ID = 2, Name = "标签222222" });
11 
12 
13         this.DataContext = mainviewmodel;
14     }
15 }

7、运行,可以看到界面显示如下:

8、增加编辑功能

需要为编辑界面增加一个ViewModel,在这个ViewModel中定义显示在界面上的字段,并增加一个保存命令

 1 public class DataEditViewModel : INotifyPropertyChanged
 2 {
 3     public event PropertyChangedEventHandler PropertyChanged;
 4 
 5     public void RaiseChanged([CallerMemberName] string propName = "")
 6     {
 7         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
 8     }
 9 
10     private int id;
11     private string name;
12 
13     public int Num
14     {
15         get => id;
16         set
17         {
18             id = value;
19             RaiseChanged();
20         }
21     }
22 
23     public string Name
24     {
25         get => name;
26         set
27         {
28             name = value;
29             RaiseChanged();
30         }
31     }
32 
33     private CommandBase saveCommand;
34     public CommandBase SaveCommand
35     {
36         get
37         {
38             if (saveCommand == null)
39             {
40                 saveCommand = new CommandBase();
41                 saveCommand.DoExecute = new Action<object>(obj => {
42                     var window = obj as Window;
43 
44                     if (window != null)
45                         window.DialogResult = true;
46                 });
47             }
48 
49             return saveCommand;
50         }
51     }
52 }

9、回到前面定义的Student类,将EditCommand补全

因为一个数据对象就是表格的一行,所以这个编辑命令需要定义在实体类中。

 1  public CommandBase EditCommand
 2  {
 3      get
 4      {
 5          if (editCommand == null)
 6          {
 7              editCommand = new CommandBase();
 8              editCommand.DoExecute = new Action<object>(obj => {
 9                  var connectData = obj as Student;
10                  DataEditView dataEditView = new DataEditView();
11                  DataEditViewModel dataEditViewModel = new DataEditViewModel();
12                  dataEditViewModel.Num = connectData.ID;
13                  dataEditViewModel.Name = connectData.Name;
14                  dataEditView.DataContext = dataEditViewModel;
15 
16                  if(dataEditView.ShowDialog() == true)
17                  {
18                      connectData.ID = dataEditViewModel.Num;
19                      connectData.Name = dataEditViewModel.Name;
20                  }
21              });
22          }
23          return editCommand;
24      }
25 
26  }

10、单击编辑链接,就可以弹出 一个新窗口进行编辑,编辑完成后,数据会更新到DataGrid中去。

示例代码

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

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

相关文章

Data+AI下的云数仓未来已来!

DataAI下的云数仓未来已来&#xff01; 前言云数仓是什么&#xff1f;云数仓的概念与背景数据孤岛问题与云数仓的优势 现代数仓如何建设&#xff1f;灵活架构与弹性扩展实时与离线处理并存安全与合规性&#xff1a;现代数仓的基石 AI如何助力数仓建设&#xff1f;AI驱动的数据处…

《探索 NESMA:软件度量领域的璀璨之星》

《探索 NESMA&#xff1a;软件度量领域的璀璨之星》 一、NESMA 初印象 NESMA&#xff08;Netherland Software Measurement Association&#xff09;&#xff0c;作为荷兰软件度量协会的简称&#xff0c;在软件规模度量领域占据着重要地位。它是五种 ISO 国际功能点标准之一&am…

C++学习路线(二十二)

构造函数 构造函数作用 在创建一个新的对象时&#xff0c;自动调用的函数&#xff0c;用来进行“初始化”工作:对这个对象内部的数据成员进行初始化。 构造函数特点 1.自动调用(在创建新对象时&#xff0c;自动调用) 2.构造函数的函数名&#xff0c;和类名相同 3.构造函数…

visual studio设置修改文件字符集方法

该方法来自网文&#xff0c;特此记录备忘。 添加两个组件&#xff0c;分别是Force UTF-8,FileEncoding。 截图如下&#xff1a; 方法如下&#xff1a;vs中点击“扩展”->“管理扩展”&#xff0c;输入utf搜索&#xff0c;安装如下两个插件&#xff0c;然后重启vs&#xf…

Cursor零基础小白教程系列 - 创建你的第一个Cursor 项目

最适合小白零基础的Cursor教程 网站lookai.top相同作者&#xff0c;最新文章会在网站更新&#xff0c;欢迎收藏书签 创建你的第一个Cursor 项目 实操视频 概述 开始使用Cursor进行编程的第一步是创建或导入一个项目。本指南将帮助您了解如何在Cursor中创建新项目、导入现有项…

GPB外链:独立站SEO提升的必备利器!

为什么GPB外链这么受欢迎&#xff1f;这主要是因为它能显著提升网站的权威性和可见性。每一条GPB外链都来自高权重的独立域名&#xff0c;并附有一篇与网站主题高度相关的原创文章。这样的外链&#xff0c;不仅对提升网站排名有帮助&#xff0c;还能为你带来更多的精准流量。 与…

Konva框选移动

效果&#xff0c;可以单独点击控制大小&#xff0c;也可框选控制 代码&#xff1a; <template><div class"rect"><div id"canvas"></div> <!-- 画布容器 --></div> </template><script setup lang"ts&…

【JVM】—G1 GC日志详解

G1 GC日志详解 ⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 文章目录 G1 GC日志详解1 G1 GC周期2 G1日…

老牌Trans也放量灌水中?年刊文量1000+,网友分享3个月可录,0版面费!

【SciencePub学术】今天给大家推荐的是一本计算机领域的SCI—《IEEE TRANSACTIONS ON ELECTRON DEVICES》&#xff0c;IEEE-Trans系列&#xff0c;虽然常年只能位居2区&#xff0c;不过投稿难度相对较低&#xff0c;所以还是深受大家喜爱的。 期刊概况 IF&#xff1a;2.9 分…

【计算机网络 - 基础问题】每日 3 题(五十四)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…

Spring事务的七种传播行为

Spring事务的七种传播行为 1.事务的传播行为是什么&#xff1f;2.具体传播行为2.1 REQUIRED &#xff0c;默认&#xff0c;存在事务则加入该事务&#xff0c;不存在则新建一个事务2.2 REQUIRES_NEW&#xff0c;每次新开启事务&#xff0c;新老事务相互独立2.3 NESTED&#xff0…

ArcGIS无插件加载(无偏移)在线天地图高清影像与街道地图指南

在地理信息系统&#xff08;GIS&#xff09;的应用中&#xff0c;加载高清影像与街道地图对于地图制图、影像查阅、空间数据分析等工作至关重要。天地图作为官方出品的地图服务&#xff0c;以其标准的数据、较快的影像更新速度等特点受到广泛欢迎。以下是如何在ArcGIS中无插件加…

创建项目模版

一 Vite创建Vue3项目 1.1.创建Vue3项目 1.1.1.运行创建项目命令 # 使用 npm npm create vitelatest 1.1.2、填写项目名称 1.1.3、选择前端框架 1.1.4、选择语法类型 1.1.5、按提示运行代码 1.1.6浏览器问 localhost:5173 预览 1.2项目结构 1.2.1vite.config.ts 1.2.2 pac…

【股票】——1-50篇,第一本

一、背景 偶然间在朋友圈看到了雪球花甲老头的公众号&#xff0c;里面的宏观观点和微观观点讲的都太好了&#xff1b;因为作者有那样的经历&#xff0c;所以才能写出来那样的内容&#xff1b;关于股市的&#xff0c;总共500篇&#xff0c;自己也计划系统性的看一看&#xff1b;…

MissingSemester-版本控制系统Git

title: Git的底层及基础使用 date: 2024-05-16 12:00:00 categories: MissingSemester tags: 版本控制系统Git 版本控制系统Git 什么是Git ​ 版本控制系统 (VCSs) 是一类用于追踪源代码&#xff08;或其他文件、文件夹&#xff09;改动的工具。顾名思义&#xff0c;这些工具…

2024年第九期 | CCF ODC《开源战略动态月报》

点击蓝字 关注我们 CCF Opensource Development Committee 导 读 2024年第九期CCF ODC《开源战略动态月报》共摘选33篇文章&#xff0c;分为8个版块&#xff1a;ODC专栏、开源政策、理论观点、产业动态、技术项目、开源组织与机构、开源报告通讯会议以及RISC-V专栏&#xff0c;…

Webserver(1)Linux开发环境搭建

目录 配置软件虚拟机中安装ubuntu安装ubuntu18的操作系统 安装VM tools安装XshellVscode远程连接到虚拟机 配置软件 VMwareVScodeg安装ubuntu 18.04.iso 或者镜像版本 XShellXFTP 虚拟机中安装ubuntu 安装ubuntu18的操作系统 开启虚拟机 选择中文简体 安装VM tools 打开v…

V2X介绍

文章目录 什么是V2XV2X的发展史早期的DSRC后起之秀C-V2XC-V2X 和DSRC 两者的对比 什么是V2X 所谓V2X&#xff0c;与流行的B2B、B2C如出一辙&#xff0c;意为vehicle to everything&#xff0c;即车对外界的信息交换。车联网通过整合全球定位系统&#xff08;GPS&#xff09;导…

Java基础-注解机制详解

文章目录 注解基础Java内置注解内置注解- Override内置注解 - Deprecated内置注解 - SuppressWarnings 元注解元注解 - Target元注解 - Retention & RetentionTarget元注解 - Documented元注解 - Inherited 注解与反射接口自定义注解 深入理解注解Java8提供了哪些新的注解&…

如何高效集成聚水潭数据至MySQL-技术案例解析

如何高效集成聚水潭数据至MySQL-技术案例解析 聚水潭数据集成到MySQL的技术案例分享 在本次技术案例中&#xff0c;我们将探讨如何通过轻易云数据集成平台&#xff0c;将聚水潭的店铺信息高效地集成到MySQL数据库中。具体方案为“聚水潭-店铺信息查询-->BI崛起-店铺信息表”…