WPF MVVM模式实现DataGrid编辑

本文是一个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中去。

示例代码

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(3) c++基本代码

main函数 main函数只有可执行程序才需要&#xff0c;如果是动态库等则无需main函数。 main函数标准的写法是 #include <iostream> using namspace std; int main(void) {// 业务代码return 0; } 当然以上代码只是最简单的案例&#xff0c;其中代表main函数值是int&#…

TypeScript中 元组、枚举enum、type

元组&#xff1a; let arr : [string, number] [hello, 3]; let arr2 : [number, boolean?] [44];//问号可选的let arr3 : [number, ...string[]] [34, a, b, c];//任意多个字符串&#xff0c;也可以没有 let arr4 : [number, ...string[]] [34]; 枚举&#xff1a; //e…

【C++进阶】之C++11的简单介绍(一)

&#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f49a;代码仓库&#xff0c;欢迎访问 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f30f; 任尔江湖满血骨&#xff0c;我自踏雪寻梅香。 万千浮云遮碧…

【CSS、JS】监听transitionend多次触发的原因

现有代码如下&#xff0c;移入红色内容区域触发动画&#xff0c;监听动画触发&#xff0c;但是每次触发控制台会打印4次 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content…

低功耗4G模组采集温湿度传感器数据~ 超全教程!不会的小伙伴看这篇!

在物联网&#xff08;IoT&#xff09;快速发展的今天&#xff0c;温湿度传感器作为环境监测的重要设备&#xff0c;被广泛应用于农业、工业、智慧城市等领域。本文将详细介绍如何使用低功耗4G模组Air780E采集温湿度传感器数据并实现网页查看&#xff0c;帮助初学者快速上手。 一…

springboot汉妆养生会馆网站-计算机毕业设计源码96229

目录 摘要 Abstract 1 绪论 1.1选题背景 1.2研究意义 1.3系统开发目标 2相关技术介绍 2.1 Java编程语言 2.2 B/S模式 2.3 MySQL简介 2.4 SpringBoot框架 3.汉妆养生会馆网站的设计与实现系统分析 3.1 可行性分析 3.1.1技术可行性分析 3.1.2经济可行性分析 3.1.3…

canvas小蜘蛛

一. 效果 二. 代码 <!--* Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git* Date: 2024-10-2…

【视频混剪Demo】FFmpeg的使用【Windows】

#1024程序员节 | 征文# 目录 一、简介 二、音频素材页 2.1 功能描述 &#x1f449; 搜索 &#x1f449; 添加 &#x1f449; 删除 2.2 效果展示 2.3 代码实现 &#x1f449; 前端 &#x1f449; 后端 三、视频素材页 3.1 功能描述 &#x1f449; 搜索 &#x1…

【2024CANN训练营第二季】使用华为云体验AscendC_Sample仓算子运行

环境介绍 NPU&#xff1a;Ascend910B2 环境准备 创建Notebook 华为云选择&#xff1a;【控制台】-【ModelArts】 ModelArts主页选择【开发生产】-【开发空间】-【Notebook】 页面右上角选择【创建Notebook】 选择资源 主要参数 规格&#xff1a;Ascend: 1*ascend-snt…

微搭低代码学习1:不同页面传递值

这个系列逐渐学习低代码平台&#xff0c;补足因为技术栈不足带来的问题&#xff0c;同时借助低代码平台快速搭建成型的系统。 这个博客用来记录一个非常常见的操作&#xff0c;在两个页面/多个页面之间传递值 文章目录 1. 创建页面2. 添加逻辑主动跳转页逻辑设置数据接收页逻辑…

【数据结构与算法】之栈详解

栈&#xff08;Stack&#xff09;是一种基本的线性数据结构&#xff0c;遵循后进先出、先进后出的原则。本文将更详细地介绍栈的概念、特点、Java 实现以及应用场景。 1. 栈概念概述 想象一摞叠放的盘子&#xff0c;你只能从最上面取盘子&#xff0c;放盘子也只能放在最上面。…

html和css实现页面

任务4 html文件 任务5 htm文件 css文件 任务6 html文件 css文件 任务7 html文件 css文件

工业交换机的电源类型

工业交换机的电源通常有以下几种类型和注意事项&#xff1a; 1. 电源类型&#xff1a; 交流电源&#xff08;AC&#xff09;&#xff1a;一些工业交换机使用标准的AC电源&#xff0c;通常是110V或220V。适用于有稳定电源环境的场合。 直流电源&#xff08;DC&#xff09;&#…

javaWeb项目-ssm+jsp大学生校园兼职系统功能介绍

本项目源码&#xff08;点击下方链接下载&#xff09;&#xff1a;java-ssmjsp大学生校园兼职系统实现源码(项目源码-说明文档)资源-CSDN文库 项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#x…

使用Selenium时,如何模拟正常用户行为?

Selenium作为自动化测试和网页数据抓取的利器&#xff0c;被广泛应用于自动化网页交互、爬虫开发等领域。然而&#xff0c;随着网站反爬虫技术的不断升级&#xff0c;简单的自动化脚本很容易被识别和阻止。因此&#xff0c;模拟正常用户行为&#xff0c;降低被检测的风险&#…

springmvc+jdk1.8升级到springboot3+jdk17(实战)

1.查找springboot3官方要求 这里查的是springboot 3.2.6版本的 2.升级jdk到17 Java EE 8之后&#xff0c;Oracle在19年把javax捐给了eclipse基会&#xff0c;但不允许使用javax的命名空间&#xff0c;所以eclipse才发展成为现在的Jakarta ee标准。Springboot3后使用Jakarta a…

HTML简单版的体育新闻案例

代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>Document</title> &l…

使用QT绘图控件QCustomPlot绘制波形图

使用QT绘图控件QCustomPlot绘制波形图 下载QCustomPlot 下载QCustomPlot,链接路径 解压之后就能看到源代码了 在Qt中添加QCustomPlot的帮助文档 在Qt Creator的菜单:工具–>选项–>帮助–>文档–>添加qcustomplot\documentation\qcustomplot.qch文件。

windbg调试exedump步骤,技巧总结

所有信息参考官方文档&#xff1a;开始使用 WinDbg&#xff08;用户模式&#xff09; - Windows drivers | Microsoft Learn 需要着重关注的标签页如下&#xff1a; 用户模式&#xff08;入门&#xff09; 命令摘要 Help 菜单上的命令 Contents.sympath&#xff08;设置符号…

解锁PDF权限密码

目录 背景: 定义与功能&#xff1a; 过程&#xff1a; 主要功能&#xff1a; 使用方式&#xff1a; 使用限制&#xff1a; 注意事项&#xff1a; 总结&#xff1a; 背景: 前段时间自己设置了PDF文件的许可口令&#xff0c;忘了口令导致自己无法编辑内容等&#xff0c;这…