WPF Demo(MVVM设计模式)


WPF MVVM设计模式实例

本人是WPF初学者,以下实例仅为本人的理解,如有错漏欢迎补充。

我们先看成品样图,并一步一步按此效果完成。

 

 

 

开发环境:Win10、VS2019

(一)实现将学生信息显示与主界面功能。

1.使用WPF模板创建一个项目。

 

2.新建Model类Student,其中继承的ViewModdelBase需要安装MvvmLightLibs库。

 1 public class Student : ViewModelBase
 2     {
 3         /// <summary>
 4         /// id
 5         /// </summary>
 6         private int id;
 7         public int Id
 8         {
 9             get { return id; }
10             set { id = value; RaisePropertyChanged(); }
11         }
12 
13         /// <summary>
14         /// 姓名
15         /// </summary>
16         private string name;
17         public string Name
18         {
19             get { return name; }
20             set { name = value; RaisePropertyChanged(); }
21         }
22 
23         /// <summary>
24         /// 性别
25         /// </summary>
26         private string sex;
27         public string Sex
28         {
29             get { return sex; }
30             set { sex = value; RaisePropertyChanged(); }
31         }
32 
33         /// <summary>
34         /// 爱好
35         /// </summary>
36         private string hobby;
37         public string Hobby
38         {
39             get { return hobby; }
40             set { hobby = value; RaisePropertyChanged(); }
41         }
42 
43         /// <summary>
44         /// 出生日期
45         /// </summary>
46         private DateTime birthDate;
47         public DateTime BirthDate
48         {
49             get { return birthDate; }
50             set { birthDate = value; RaisePropertyChanged(); }
51         }
52     }

 

3.新建LocalDb类作为本地内存数据库,并支持新增、删除和查询功能。因为MVVM设计模式有通知属性变化的功能,所以自带了修改的效果。

 1 public class LocalDb
 2     {
 3         public LocalDb()
 4         {
 5             Init();
 6         }
 7 
 8         List<Student> lstStu;
 9         public void Init()
10         {
11             lstStu = new List<Student>
12             {
13                 new Student
14                 {
15                     Id = 1,
16                     Name = "小明",
17                     Sex = "",
18                     Hobby = "篮球、跑步",
19                     BirthDate = Convert.ToDateTime("2014/1/14")
20                 },
21                 new Student
22                 {
23                     Id = 2,
24                     Name = "小红",
25                     Sex = "",
26                     Hobby = "跳绳",
27                     BirthDate = Convert.ToDateTime("2014/5/19")
28                 },
29                 new Student
30                 {
31                     Id = 3,
32                     Name = "小军",
33                     Sex = "",
34                     Hobby = "足球",
35                     BirthDate = Convert.ToDateTime("2013/11/14")
36                 },
37                 new Student
38                 {
39                     Id = 4,
40                     Name = "小芳",
41                     Sex = "",
42                     Hobby = "唱歌、画画",
43                     BirthDate = Convert.ToDateTime("2014/3/5")
44                 },
45                 new Student
46                 {
47                     Id = 5,
48                     Name = "小李",
49                     Sex = "",
50                     Hobby = "武术",
51                     BirthDate = Convert.ToDateTime("2014/10/25")
52                 }
53             };
54         }
55 
56         public Student GetStudentById(int id)
57         {
58             var data = lstStu.FirstOrDefault(o => o.Id == id);
59             return data;
60         }
61 
62         public List<Student> GetStudentByName(string name)
63         {
64             var dataList = lstStu.FindAll(o => o.Name.Contains(name));
65             return dataList;
66         }
67 
68         public void Add(Student stu)
69         {
70             if (stu != null)
71             {
72                 lstStu.Add(stu);
73             }
74         }
75 
76         public void Del(int id)
77         {
78             var data = lstStu.FirstOrDefault(o => o.Id == id);
79             if (data != null)
80             {
81                 lstStu.Remove(data);
82             }
83         }
84     }

 

4.新建一个ViewStudentModel类,用于创建视图与模型间增删改查操作命令。我们先来把查询功能做出来,然后看一下运行效果。

 1 public class ViewStudentModel : ViewModelBase
 2     {
 3         private string search = string.Empty;
 4         public string Search
 5         {
 6             get { return search; }
 7             set { search = value; RaisePropertyChanged(); }
 8         }
 9 
10         private ObservableCollection<Student> gridModelList;
11         public ObservableCollection<Student> GridModelList
12         {
13             get { return gridModelList; }
14             set { gridModelList = value; RaisePropertyChanged(); }
15         }
16 
17         public RelayCommand QueryCommand { get; set; }
18 
19         private LocalDb localDb;
20         public ViewStudentModel()
21         {
22             localDb = new LocalDb();
23             QueryCommand = new RelayCommand(Query);
24         }
25 
26         public void Query()
27         {
28             var dataList = localDb.GetStudentByName(Search);
29             GridModelList = new ObservableCollection<Student>();
30             if (dataList != null)
31             {
32                 dataList.ForEach(o => GridModelList.Add(o));
33             }
34         }
35     }

 

5.在主程序MainWindow.cs类初始化ViewStudentModel类,并调用查询命令,给DataContext赋值,用于UI界面绑定数据。

1 public MainWindow()
2         {
3             InitializeComponent();
4 
5             var view = new ViewStudentModel();
6             view.Query();
7 
8             this.DataContext = view;
9         }

 

6.编写UI界面。

 1 <Window x:Class="WpfMVVMDemo.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:WpfMVVMDemo"
 7         mc:Ignorable="d"
 8         WindowStartupLocation="CenterScreen"
 9         Title="MainWindow" Height="450" Width="800">
10     <Grid>
11         <Grid.RowDefinitions>
12             <RowDefinition Height="60"></RowDefinition>
13             <RowDefinition></RowDefinition>
14         </Grid.RowDefinitions>
15 
16         <StackPanel Orientation="Horizontal">
17             <TextBlock Text="搜索:" VerticalAlignment="Center" FontSize="16" Margin="10 0 0 0"></TextBlock>
18             <TextBox Text="{Binding Search}" Width="180" Height="25" Margin="10 0 0 0"></TextBox>
19             <Button Command="{Binding QueryCommand}" Content="查询" Width="75" Height="25" Margin="10 0 0 0"></Button>
20             <Button Content="新增" Width="75" Height="25" Margin="10 0 0 0"></Button>
21             <Button Content="重置" Width="75" Height="25" Margin="10 0 0 0"></Button>
22         </StackPanel>
23 
24         <DataGrid Grid.Row="1" IsReadOnly="True" ItemsSource="{Binding GridModelList}" AutoGenerateColumns="False" ColumnWidth="*">
25             <DataGrid.Columns>
26                 <DataGridTextColumn Header="Id" Binding="{Binding Id}">
27                 </DataGridTextColumn>
28                 <DataGridTextColumn Header="姓名" Binding="{Binding Name}">
29                 </DataGridTextColumn>
30                 <DataGridTextColumn Header="性别" Binding="{Binding Sex}">
31                 </DataGridTextColumn>
32                 <DataGridTextColumn Header="爱好" Binding="{Binding Hobby}">
33                 </DataGridTextColumn>
34                 <DataGridTextColumn Header="出生日期" Binding="{Binding BirthDate, StringFormat='yyyy/MM/dd'}">
35                 </DataGridTextColumn>
36                 <DataGridTemplateColumn Header="操作">
37                     <DataGridTemplateColumn.CellTemplate>
38                         <DataTemplate>
39                             <StackPanel Orientation="Horizontal">
40                                 <Button Content="修改" Width="60" Height="25" Foreground="Black" Background="Yellow"></Button>
41                                 <Button Content="删除" Width="60" Height="25" Foreground="Black" Background="Red"></Button>
42                             </StackPanel>
43                         </DataTemplate>
44                     </DataGridTemplateColumn.CellTemplate>
45                 </DataGridTemplateColumn>
46             </DataGrid.Columns>
47         </DataGrid>
48     </Grid>
49 </Window>

此时我们运行就能看到数据了,并且查询功能也可以使用了。

 

(二)完善新增、修改、删除和重置数据功能。

1.我们先完成简单的删除功能。

首先在ViewStudentModel.cs添加删除命令。

 1 public RelayCommand<int> DelCommand { get; set; }
 2 
 3 public ViewStudentModel()
 4         {
 5             localDb = new LocalDb();
 6             QueryCommand = new RelayCommand(Query);
 7             DelCommand = new RelayCommand<int>(Del);
 8         }
 9 
10 public void Del(int id)
11         {
12             var data = localDb.GetStudentById(id);
13             if (data != null)
14             {
15                 var r = MessageBox.Show($"是否删除学生:{data.Name}?", "删除学生", MessageBoxButton.YesNoCancel);
16                 if (r == MessageBoxResult.Yes)
17                 {
18                     localDb.Del(id);
19                     Query();
20                 }
21                 
22             }
23         }

 然后在UI界面使用删除命令。

1 <Button Content="删除" Width="60" Height="25" Foreground="Black" Background="Red"
2                                         CommandParameter="{Binding Id}"
3                                         Command="{Binding DataContext.DelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}">
4                                 </Button>

 

2.接着,我们再完成比较简单的重置功能。

跟删除功能的实现类似,首先在ViewStudentModel.cs添加重置命令。

 1 public RelayCommand<int> DelCommand { get; set; }
 2 
 3 public ViewStudentModel()
 4         {
 5             localDb = new LocalDb();
 6             QueryCommand = new RelayCommand(Query);
 7             ResetCommand = new RelayCommand(Reset);
 8             DelCommand = new RelayCommand<int>(Del);
 9         }
10 
11 public void Reset()
12         {
13             Search = string.Empty;
14             localDb.Init();
15             Query();
16         }

然后在UI界面使用重置命令。

1 <Button Command="{Binding ResetCommand}" Content="重置" Width="75" Height="25" Margin="10 0 0 0"></Button>

 

3.添加新增功能。

3.1.新建一个WPF窗体ViewStudent,编写UI界面。

 1 <Window x:Class="WpfMVVMDemo.Views.ViewStudent"
 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:WpfMVVMDemo.Views"
 7         mc:Ignorable="d"
 8         WindowStartupLocation="CenterScreen"
 9         Title="ViewStudent" Height="300" Width="300">
10     <Grid>
11         <Grid.RowDefinitions>
12             <RowDefinition Height="40"></RowDefinition>
13             <RowDefinition></RowDefinition>
14             <RowDefinition Height="40"></RowDefinition>
15         </Grid.RowDefinitions>
16 
17         <TextBlock Text="{Binding Title}" FontSize="14" HorizontalAlignment="Left" Margin="10 0 0 0"></TextBlock>
18 
19         <Grid Grid.Row="1">
20             <Grid.ColumnDefinitions>
21                 <ColumnDefinition Width="100"></ColumnDefinition>
22                 <ColumnDefinition></ColumnDefinition>
23             </Grid.ColumnDefinitions>
24 
25             <StackPanel Orientation="Vertical"  HorizontalAlignment="Right">
26                 <TextBlock Text="姓名:" Height="25" Margin="0 0 0 0"></TextBlock>
27                 <TextBlock Text="性别:" Height="25" Margin="0 20 0 0"></TextBlock>
28                 <TextBlock Text="爱好:" Height="25" Margin="0 20 0 0"></TextBlock>
29                 <TextBlock Text="出生日期:" Height="25" Margin="0 20 0 0"></TextBlock>
30             </StackPanel>
31 
32             <StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Left">
33                 <TextBox Text="{Binding Model.Name}" Width="150" Height="25" Margin="0 0 0 0"></TextBox>
34                 <ComboBox x:Name="cbSex" Text="{Binding Model.Sex}" Width="150" Height="25" Margin="0 20 0 0"></ComboBox>
35                 <TextBox Text="{Binding Model.Hobby}" Width="150" Height="25" Margin="0 20 0 0"></TextBox>
36                 <DatePicker Text="{Binding Model.BirthDate}" Width="150" Height="25" Margin="0 20 0 0"></DatePicker>
37             </StackPanel>
38         </Grid>
39 
40         <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
41             <Button x:Name="btnSave" Click="btnSave_Click" Content="确定" Width="60" Height="25" Margin="0 0 10 0"></Button>
42             <Button x:Name="btnCancel" Click="btnCancel_Click" Content="取消" Width="60" Height="25" Margin="0 0 10 0"></Button>
43         </StackPanel>
44     </Grid>
45 </Window>

3.2.初始化页面资源,使用构造方法接收Model。

 1 public partial class ViewStudent : Window
 2     {
 3         private List<string> lstSex = new List<string>
 4         {
 5             "","","未知"
 6         };
 7 
 8         public ViewStudent(string title, Student stu)
 9         {
10             InitializeComponent();
11 
12             this.DataContext = new
13             {
14                 Model = stu,
15                 Title = title
16             };
17 
18             cbSex.ItemsSource = lstSex;
19             if (title.Equals("新增学生:"))
20             {
21                 stu.BirthDate = DateTime.Now;
22             }
23         }
24 
25         private void btnCancel_Click(object sender, RoutedEventArgs e)
26         {
27             this.DialogResult = false;
28         }
29 
30         private void btnSave_Click(object sender, RoutedEventArgs e)
31         {
32             this.DialogResult = true;
33         }
34     }

3.3.然后跟重置功能的实现类似,首先在ViewStudentModel.cs添加新增命令。

 1 public RelayCommand AddCommand { get; set; }
 2 
 3 public ViewStudentModel()
 4         {
 5             localDb = new LocalDb();
 6             QueryCommand = new RelayCommand(Query);
 7             AddCommand = new RelayCommand(Add);
 8             ResetCommand = new RelayCommand(Reset);
 9             DelCommand = new RelayCommand<int>(Del);
10         }
11 
12 public void Add()
13         {
14             var stu = new Student();
15             var view = new ViewStudent("新增学生:", stu);
16             var r = view.ShowDialog();
17             if (r.Value)
18             {
19                 stu.Id = GridModelList.Max(o => o.Id) + 1;
20                 localDb.Add(stu);
21                 Query();
22             }
23         }

3.4.最后在UI界面使用新增命令。

1 <Button Command="{Binding AddCommand}" Content="新增" Width="75" Height="25" Margin="10 0 0 0"></Button>

 

4.添加编辑功能。因为已经完成添加功能,我们可以继续使用ViewStudent页面,只要将标题改成修改就好了。

4.1.跟删除功能的实现类似,首先在ViewStudentModel.cs添加编辑命令。

 1 public RelayCommand<int> EditCommand { get; set; }
 2 
 3 public ViewStudentModel()
 4         {
 5             localDb = new LocalDb();
 6             QueryCommand = new RelayCommand(Query);
 7             AddCommand = new RelayCommand(Add);
 8             EditCommand = new RelayCommand<int>(Edit);
 9             ResetCommand = new RelayCommand(Reset);
10             DelCommand = new RelayCommand<int>(Del);
11         }
12 
13 public void Edit(int id)
14         {
15             var data = localDb.GetStudentById(id);
16             if (data != null)
17             {
18                 var tData = new Student
19                 {
20                     Id = data.Id,
21                     Name = data.Name,
22                     Sex = data.Sex,
23                     Hobby = data.Hobby,
24                     BirthDate = data.BirthDate
25                 };
26 
27                 var view = new ViewStudent("编辑学生:", data);
28                 var r = view.ShowDialog();
29                 if (!r.Value)
30                 {
31                     var model = GridModelList.FirstOrDefault(o => o.Id == id);
32                     model.Name = tData.Name;
33                     model.Sex = tData.Sex;
34                     model.Hobby = tData.Hobby;
35                     model.BirthDate = tData.BirthDate;
36                 }
37             }
38         }

4.2.然后在UI界面使用修改命令。

1 <Button Content="修改" Width="60" Height="25" Foreground="Black" Background="Yellow"
2                                         CommandParameter="{Binding Id}"
3                                         Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"></Button>

到现在为止,我们把一个使用MVVM设计模式的WPF项目完成了,并且具有最基本的增删改查功能。

 本实例源码:https://github.com/Jcanc/WpfMVVMDemo.git


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM