WPF MVVM实现数据增删改查逻辑全流程详细解析demo
界面总览
gitee 地址:WPFMVVM: 使用mvvm模拟实现数据增删改查 (gitee.com)
本例中包含两个View 界面:MainWindow.xaml 数据列表界面,StudentView.xaml数据新增编辑界面
本例使用了命令绑定MvvmLight RelayCommand模拟数据增删改查操作,适用于WPF入门阅读
效果如下:
程序代码结构:
添加Nuget包引用
实现程序主界面xaml代码
<Window x:Class="WpfMvvm.MainWindow" 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:local="clr-namespace:WpfMvvm" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Width="800" Height="450" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition /> Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> <TextBlock Margin="10,0,0,0" VerticalAlignment="Center" Text="搜索条件" /> <TextBox x:Name="QueryBox" Width="200" Height="25" Margin="10,0,0,0" VerticalContentAlignment="Center" Text="{Binding Search}" /> <Button x:Name="QuertyButton" Width="30" Margin="10,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding QueryCommand}" Content="查询" /> <Button x:Name="ResetButton" Width="30" Margin="10,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding ResetCommand}" Content="重置" /> <Button x:Name="AddButton" Width="30" Margin="10,0,0,0" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding AddCommand}" Content="新增" /> StackPanel> <DataGrid Grid.Row="1" AutoGenerateColumns="False" CanUserAddRows="False" ColumnWidth="*" ItemsSource="{Binding Students}"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Id}" Header="序号" /> <DataGridTextColumn Binding="{Binding Name}" Header="姓名" /> <DataGridTemplateColumn Width="100" Header="操作"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Button x:Name="gridEdit" Width="30" Height="20" Margin="10,0,0,0" Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" CommandParameter="{Binding Id}" Content="编辑" /> <Button x:Name="gridDele" Width="30" Height="20" Margin="10,0,0,0" Command="{Binding DataContext.DeleCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" CommandParameter="{Binding Id}" Content="删除" /> StackPanel> DataTemplate> DataGridTemplateColumn.CellTemplate> DataGridTemplateColumn> DataGrid.Columns> DataGrid> Grid> Window>
在ViewModel文件夹中添加MainViewModel
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using System.Collections.ObjectModel; using WpfMvvm.DB; using WpfMvvm.Models; using WpfMvvm.View; using System.Linq; using System.Windows; namespace WpfMvvm.ViewModel { public class MainViewModel : ViewModelBase { LocalDb localDb; public MainViewModel() { localDb = new LocalDb(); QueryCommand = new RelayCommand(Query); ResetCommand = new RelayCommand(Reset); AddCommand = new RelayCommand(Add); EditCommand = new RelayCommand<int>(Edit); DeleCommand = new RelayCommand<int>(Dele); } private void Dele(int id) { if (MessageBox.Show("确认删除?","提示",MessageBoxButton.YesNo, MessageBoxImage.Question)== MessageBoxResult.Yes) { this.localDb.DeleteStudent(id); this.Query(); } } private void Edit(int id) { var student = this.localDb.GetStudentsID(id); StudentView studentView = new StudentView(); studentView.WindowStartupLocation = WindowStartupLocation.CenterOwner; studentView.SetStudent(student); var dialog = studentView.ShowDialog(); if (dialog == true) { student = this.Students.FirstOrDefault(x => x.Id == student.Id); student.Name = studentView.GetStudent().Name; } } private void Add() { Student student = new Student(); StudentView studentView = new StudentView(); studentView.WindowStartupLocation = WindowStartupLocation.CenterOwner; studentView.SetStudent(student); var dialog = studentView.ShowDialog(); if (dialog == true) { student = studentView.GetStudent(); student.Id = this.Students.Max(x => x.Id) + 1; localDb.AddStudent(student); this.Query(); } } private void Reset() { Search = string.Empty; Query(); } public void Query() { var qstudents = localDb.GetStudentsByName(Search); Students = new ObservableCollection(); if (qstudents != null) { qstudents.ForEach(x => Students.Add(x)); } } #region command public RelayCommand QueryCommand { get; set; } public RelayCommand ResetCommand { get; set; } public RelayCommand AddCommand { get; set; } public RelayCommand<int> EditCommand { get; set; } public RelayCommand<int> DeleCommand { get; set; } #endregion private string search; public string Search { get => search; set { search = value; RaisePropertyChanged(); } } private ObservableCollection students; public ObservableCollection Students { get => students; set { students = value; RaisePropertyChanged(); } } } }
数据编辑界面StudentView.xaml
<Window x:Class="WpfMvvm.View.StudentView" 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:local="clr-namespace:WpfMvvm.View" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Width="300" Height="300" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition /> <RowDefinition Height="60" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Margin="10,0,0,0" VerticalAlignment="Center" FontWeight="Bold" Text="学生信息编辑" /> <StackPanel Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Horizontal"> <TextBlock Margin="0,0,10,0" Text="姓名" /> <TextBox Width="100" Text="{Binding Student.Name}" /> </StackPanel> <StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal"> <Button Width="30" Height="22" Margin="0,0,10,0" Command="{Binding ApplyCommand}" Content="确定" /> <Button Width="30" Height="22" Margin="0,0,10,0" Command="{Binding CancleCommand}" Content="取消" /> </StackPanel> </Grid> </Window>
StudentViewModel实现类
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using WpfMvvm.Models; namespace WpfMvvm.ViewModel { public class StudentViewModel : ViewModelBase { public StudentViewModel() { ApplyCommand = new RelayCommand(Add); CancleCommand = new RelayCommand(Cancle); } /// <summary> /// 设置与view关联的窗体 /// </summary> /// <param name="window"></param> public void SetWindow(Window window) { this.window = window; } private void Cancle() { this.window.Close(); } private void Add() { this.window.DialogResult = true; } private Window window; private Student student; public Student Student { get => student; set { student = value; RaisePropertyChanged(); } } #region Command public RelayCommand ApplyCommand { get; set; } public RelayCommand CancleCommand { get; set; } #endregion } }
Student实体类
using GalaSoft.MvvmLight; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WpfMvvm.Models { public class Student : ViewModelBase { private int id; private string name; public int Id { get => id; set { id = value; RaisePropertyChanged(nameof(Id)); } } public string Name { get => name; set { name = value; RaisePropertyChanged(nameof(Name)); } } } }
模拟数据库存储类LocalDb,实现数据增删改查
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WpfMvvm.Models; namespace WpfMvvm.DB { public class LocalDb { public LocalDb() { Init(); } public Student GetStudentsID(int id) { return students.FirstOrDefault(student => student.Id.Equals(id)); } public List<Student> GetStudentsByName(string Name) { if (!string.IsNullOrEmpty(Name)) { return students.Where(student=> student.Name.Contains(Name)).ToList(); } return students; } private List<Student> students; private void Init() { students = new List<Student>(); for (int i = 0; i < 30; i++) { students.Add(new Student { Id = i, Name = $"Name{i}" }); } } public void DeleteStudent(int id) { var dele = this.students.FirstOrDefault(x => x.Id.Equals(id)); if (dele != null) { this.students.Remove(dele); } } public void AddStudent(Student student) { this.students.Add(student); } } }
View 与ViewModel 绑定处理
StudentView
public partial class StudentView : Window { StudentViewModel viewModel; public StudentView() { InitializeComponent(); viewModel = new StudentViewModel(); this.DataContext = viewModel; } public void SetStudent(Student student) { viewModel.SetWindow(this); viewModel.Student = new Student { Id = student.Id, Name = student.Name }; } public Student GetStudent() { return viewModel.Student; } }
MainWindow与MainViewModel
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); MainViewModel mainViewModel = new MainViewModel(); mainViewModel.Query(); this.DataContext = mainViewModel; } }