WPF develops student information management system [WPF+Prism+MAH+WebApi]

Recently, through the WPF development project, in order to summarize the WPF knowledge points, I used my spare time to develop a student information management system [Student Information Management System]. The first three articles have carried out framework construction and module division, background WebApi interface writing, and course management module development. Based on the first three articles, this article continues to further develop the class management and student management modules of the student information management system. Through this article This article will continue to consolidate the previous knowledge points. This article is only for learning and sharing. If there are any shortcomings, please correct me.

Involving knowledge points

Since the server-side development of class management and student management will be introduced later in the second article, this article focuses on the development of client-side functions. The knowledge points involved are as follows:

  1. Basic use of controls such as TextBlock, TextBox, DataGrid, Combox, and data binding in WPF development.
  2. The use of MAH style, in this example, MAH is mainly used to unify page style and improve user experience.
  3. HttpClient is mainly used to access the interface provided by the server.

Business logic

First of all, class management and student management are both related and independent from each other, unlike the course management module that exists independently and does not depend on other modules. So the two modules are put together in one article to explain. The relationship is as follows:

  1. A student belongs to a class, so the class information is included in the student.
  2. There is a monitor in the class, and the monitor is an entity of the students.

class management

1. Interface access class ClassesHttpUtil

The class data table structure and service interface have been introduced in the second article. If you have any questions, you can go to the reference. The interface access class is used to encapsulate the interface provided by the access server. As follows:

 1 namespace SIMS.Utils.Http
 2 {
 3     public class ClassesHttpUtil:HttpUtil
 4     {
 5         /// <summary>
 6         /// pass id Inquire about student information
 7         /// </summary>
 8         /// <param name="id"></param>
 9         /// <returns></returns>
10         public static ClassesEntity GetClasses(int id)
11         {
12             Dictionary<string, object> data = new Dictionary<string, object>();
13             data["id"] = id;
14             var str = Get(UrlConfig.CLASSES_GETCLASSES, data);
15             var classes = StrToObject<ClassesEntity>(str);
16             return classes;
17         }
18 
19         public static PagedRequest<ClassesEntity> GetClassess(string? dept, string? grade, int pageNum, int pageSize)
20         {
21             Dictionary<string, object> data = new Dictionary<string, object>();
22             data["dept"] = dept;
23             data["grade"] = grade;
24             data["pageNum"] = pageNum;
25             data["pageSize"] = pageSize;
26             var str = Get(UrlConfig.CLASSES_GETCLASSESS, data);
27             var classess = StrToObject<PagedRequest<ClassesEntity>>(str);
28             return classess;
29         }
30 
31         public static bool AddClasses(ClassesEntity classes) {
32             var ret = Post<ClassesEntity>(UrlConfig.CLASSES_ADDCLASSES, classes);
33             return int.Parse(ret)==0;
34         }
35 
36         public static bool UpdateClasses(ClassesEntity classes) {
37             var ret = Put<ClassesEntity>(UrlConfig.CLASSES_UPDATECLASSES, classes);
38             return int.Parse(ret) == 0;
39         }
40 
41         public static bool DeleteClasses(int Id)
42         {
43             Dictionary<string,  string> data = new Dictionary<string, string>();
44             data["Id"] = Id.ToString();
45             var ret = Delete(UrlConfig.CLASSES_DELETECLASSES, data);
46             return int.Parse(ret) == 0;
47         }
48     }
49 }

2. Client page view

There are two client page views of class management, one is the query list page, and the other is the new editing page, which together constitute the addition, deletion, modification and query of the class management.

Query the class list page, the knowledge points involved are as follows:

  1. The query condition or the data column display in the list interacts with the ViewModel through data Binding, that is, click the query button, and no longer pass parameters, because the properties in the ViewModel have been updated synchronously.
  2. Not all properties in ViewModel can implement two-way binding, only properties with notification function can be implemented. In the Prism framework, it can be quickly implemented through the SetProperty method of BindableBase.
  3. In the View view, if there is a Command command in the control, it can be bound directly. If it does not exist, the event can be converted into a command by i:Interaction.Triggers, such as the Load event.
  4. In the list, if you need to add buttons, you can customize the data through DataTemplate.

Query the class page code as follows:

  1 <UserControl x:Class="SIMS.ClassesModule.Views.Classes"
  2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6              xmlns:local="clr-namespace:SIMS.ClassesModule.Views"
  7              xmlns:prism="http://prismlibrary.com/"
  8              xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
  9              xmlns:mahApps="http://metro.mahapps.com/winfx/xaml/controls"
 10              xmlns:ctrls ="clr-namespace:SIMS.Utils.Controls;assembly=SIMS.Utils"
 11              prism:ViewModelLocator.AutoWireViewModel="True"
 12              mc:Ignorable="d" 
 13              d:DesignHeight="450" d:DesignWidth="800">
 14     <UserControl.Resources>
 15         <ResourceDictionary>
 16             <ResourceDictionary.MergedDictionaries>
 17                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
 18                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
 19                 <ResourceDictionary>
 20                     <Style x:Key="LinkButton" TargetType="Button">
 21                         <Setter Property="Background" Value="White"></Setter>
 22                         <Setter Property="Cursor" Value="Hand"></Setter>
 23                         <Setter Property="Margin" Value="3"></Setter>
 24                         <Setter Property="MinWidth" Value="80"></Setter>
 25                         <Setter Property="MinHeight" Value="25"></Setter>
 26                         <Setter Property="BorderThickness" Value="0 0 0 0"></Setter>
 27                     </Style>
 28                 </ResourceDictionary>
 29             </ResourceDictionary.MergedDictionaries>
 30         </ResourceDictionary>
 31     </UserControl.Resources>
 32     <i:Interaction.Triggers>
 33         <i:EventTrigger EventName="Loaded">
 34             <i:InvokeCommandAction Command="{Binding LoadedCommand}"></i:InvokeCommandAction>
 35         </i:EventTrigger>
 36     </i:Interaction.Triggers>
 37     <Grid>
 38         <Grid.RowDefinitions>
 39             <RowDefinition Height="Auto"></RowDefinition>
 40             <RowDefinition Height="Auto"></RowDefinition>
 41             <RowDefinition Height="*"></RowDefinition>
 42             <RowDefinition Height="Auto"></RowDefinition>
 43         </Grid.RowDefinitions>
 44         <TextBlock Text="Class information" FontSize="20" Background="AliceBlue" Margin="2"></TextBlock>
 45         <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
 46             <TextBlock Text="specialized" VerticalAlignment="Center" Margin="2"></TextBlock>
 47             <TextBox Margin="4" MinWidth="120" Height="30"
 48                      Text="{Binding Dept}"
 49                              HorizontalContentAlignment="Stretch"
 50                              mahApps:TextBoxHelper.ClearTextButton="True"
 51                              mahApps:TextBoxHelper.Watermark="specialized"
 52                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 53                              SpellCheck.IsEnabled="True" />
 54             <TextBlock Text="grade" VerticalAlignment="Center" Margin="2"></TextBlock>
 55             <TextBox Margin="4" MinWidth="120" Height="30"
 56                      Text="{Binding Grade}"
 57                              HorizontalContentAlignment="Stretch"
 58                              mahApps:TextBoxHelper.ClearTextButton="True"
 59                              mahApps:TextBoxHelper.Watermark="grade"
 60                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 61                              SpellCheck.IsEnabled="True" />
 62             <Button Content="Inquire" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding QueryCommand}"></Button>
 63             <Button Content="new" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding AddCommand}"></Button>
 64         </StackPanel>
 65         <DataGrid x:Name="dgClasses"
 66                   Grid.Row="2"
 67                   Grid.Column="0"
 68                   Margin="2"
 69                   AutoGenerateColumns="False"
 70                   CanUserAddRows="False"
 71                   CanUserDeleteRows="False"
 72                   ItemsSource="{Binding Classes}"
 73                   RowHeaderWidth="0">
 74             <DataGrid.Columns>
 75                 <DataGridTextColumn Binding="{Binding Dept}" Header="specialized" Width="*" />
 76                 <DataGridTextColumn Binding="{Binding Grade}" Header="grade" Width="*"/>
 77                 <DataGridTextColumn Binding="{Binding Name}" Header="class" Width="*"/>
 78                 <DataGridTextColumn Binding="{Binding HeadTeacher}" Header="head teacher" Width="*"/>
 79                 <DataGridTextColumn Binding="{Binding MonitorName}" Header="monitor" Width="*" />
 80                 <DataGridTemplateColumn Header="operate" Width="*">
 81                     <DataGridTemplateColumn.CellTemplate>
 82                         <DataTemplate>
 83                             <StackPanel Orientation="Horizontal">
 84                                 <Button  Content="Edit" Style="{StaticResource LinkButton}" Command="{Binding RelativeSource={RelativeSource  AncestorType=DataGrid,  Mode=FindAncestor}, Path=DataContext.EditCommand}" CommandParameter="{Binding Id}">
 85                                     <Button.Template>
 86                                         <ControlTemplate TargetType="Button">
 87                                             <TextBlock TextDecorations="Underline" HorizontalAlignment="Center">
 88                                                 <ContentPresenter />
 89                                             </TextBlock>
 90                                         </ControlTemplate>
 91                                     </Button.Template>
 92                                 </Button>
 93                                 <Button Content="Delete" Style="{StaticResource LinkButton}" Command="{Binding RelativeSource={RelativeSource  AncestorType=DataGrid,  Mode=FindAncestor}, Path=DataContext.DeleteCommand}" CommandParameter="{Binding Id}">
 94                                     <Button.Template>
 95                                         <ControlTemplate TargetType="Button">
 96                                             <TextBlock TextDecorations="Underline" HorizontalAlignment="Center">
 97                                                 <ContentPresenter />
 98                                             </TextBlock>
 99                                         </ControlTemplate>
100                                     </Button.Template>
101                                 </Button>
102                             </StackPanel>
103                         </DataTemplate>
104                     </DataGridTemplateColumn.CellTemplate>
105                 </DataGridTemplateColumn>
106             </DataGrid.Columns>
107         </DataGrid>
108         <ctrls:PageControl Grid.Row="3" DataContext="{Binding}" ></ctrls:PageControl>
109     </Grid>
110 </UserControl>

Add edit page

The new functions and editing functions of the class share one page, and the knowledge points involved are as follows:

  1. In the newly edited ViewModel, the class entity is a property, so when data binding in the view control, you need to bring the property name, such as: Classes.Name.
  2. The monitor list has no corresponding students when adding a new class, and it can be empty. After the students are maintained, they can be selected from the student list.
  3. The monitor list is the Combox drop-down box, which is bound to the student entity list, but the client only needs to see the student's name, so the DataTemplate needs to be rewritten to display only the student's name.

Add a new class information view, the specific code is as follows:

 1 <UserControl x:Class="SIMS.ClassesModule.Views.AddEditClasses"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:SIMS.ClassesModule.Views"
 7              mc:Ignorable="d"
 8              xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
 9              xmlns:mahApps ="http://metro.mahapps.com/winfx/xaml/controls"
10              xmlns:prism="http://prismlibrary.com/"      
11              d:DesignHeight="400" d:DesignWidth="600">
12     <prism:Dialog.WindowStyle>
13         <Style TargetType="Window">
14             <Setter Property="Width" Value="600"></Setter>
15             <Setter Property="Height" Value="400"></Setter>
16         </Style>
17     </prism:Dialog.WindowStyle>
18     <UserControl.Resources>
19         <ResourceDictionary>
20             <ResourceDictionary.MergedDictionaries>
21                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
22                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
23             </ResourceDictionary.MergedDictionaries>
24         </ResourceDictionary>
25     </UserControl.Resources>
26     <i:Interaction.Triggers>
27         <i:EventTrigger EventName="Loaded">
28             <i:InvokeCommandAction Command="{Binding LoadedCommand}"></i:InvokeCommandAction>
29         </i:EventTrigger>
30     </i:Interaction.Triggers>
31     <Grid>
32         <Grid.ColumnDefinitions>
33             <ColumnDefinition Width="0.2*"></ColumnDefinition>
34             <ColumnDefinition Width="Auto"></ColumnDefinition>
35             <ColumnDefinition Width="*"></ColumnDefinition>
36             <ColumnDefinition Width="0.2*"></ColumnDefinition>
37         </Grid.ColumnDefinitions>
38         <Grid.RowDefinitions>
39             <RowDefinition></RowDefinition>
40             <RowDefinition></RowDefinition>
41             <RowDefinition></RowDefinition>
42             <RowDefinition></RowDefinition>
43             <RowDefinition></RowDefinition>
44             <RowDefinition></RowDefinition>
45             <RowDefinition></RowDefinition>
46         </Grid.RowDefinitions>
47 
48 
49         <TextBlock Text="specialized" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="3"></TextBlock>
50         <TextBox Grid.Row="0" Grid.Column="2" MinWidth="120" Height="35"  VerticalAlignment="Center" Margin="3" Text="{Binding Classes.Dept}"></TextBox>
51         <TextBlock Text="grade" Grid.Row="1" Grid.Column="1"  VerticalAlignment="Center" Margin="3"></TextBlock>
52         <TextBox Grid.Row="1" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Classes.Grade}"></TextBox>
53         <TextBlock Text="class" Grid.Row="2" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
54         <TextBox Grid.Row="2" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Classes.Name}"></TextBox>
55         <TextBlock Text="head teacher" Grid.Row="3" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
56         <TextBox Grid.Row="3" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Classes.HeadTeacher}"></TextBox>
57         <TextBlock Text="monitor" Grid.Row="4" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
58         <ComboBox Grid.Row="4" Grid.Column="2" MinWidth="120" Height="35" ItemsSource="{Binding Monitors}" mahApps:TextBoxHelper.ClearTextButton="True" SelectedItem="{Binding Monitor}">
59             <ComboBox.ItemTemplate>
60                 <DataTemplate>
61                     <TextBlock Text="{Binding Name}"></TextBlock>
62                 </DataTemplate>
63             </ComboBox.ItemTemplate>
64         </ComboBox>
65         <StackPanel Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center" Margin="3">
66             <Button Content="Cancel" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding CancelCommand}"></Button>
67             <Button Content="save" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding SaveCommand}"></Button>
68         </StackPanel>
69         <TextBlock Grid.Row="6" Grid.Column="1" Grid.ColumnSpan="2" Text="Note: When adding a new class, the monitor can be empty. After maintaining the students, the monitor can be set." Foreground="Red"></TextBlock>
70     </Grid>
71 </UserControl>

3. Client ViewModel

The class management module, corresponding to the ViewModel and the view, is also divided into the query list ViewModel and the new edit ViewModel, as shown below:

The ClassesViewModel page code is divided into three parts:

  1. Properties and constructors, mainly used for data binding, such as query conditions, lists, etc. All properties are assigned using SetProperty.
  2. Command Command, such as query, add, edit, delete commands, etc. All commands can be defined as DelegateCommand type.
  3. The paging part is omitted here because the paging function code is similar.

The specific code of ClassesViewModel is as follows:

  1 namespace SIMS.ClassesModule.ViewModels
  2 {
  3     public class ClassesViewModel :BindableBase
  4     {
  5         #region Properties and Constructors
  6 
  7         /// <summary>
  8         /// specialized
  9         /// </summary>
 10         private string dept;
 11 
 12         public string Dept
 13         {
 14             get { return dept; }
 15             set { SetProperty(ref dept , value); }
 16         }
 17 
 18         /// <summary>
 19         /// grade
 20         /// </summary>
 21         private string grade;
 22 
 23         public string Grade
 24         {
 25             get { return grade; }
 26             set { SetProperty(ref grade , value); }
 27         }
 28 
 29 
 30 
 31         private ObservableCollection<ClassesInfo> classes;
 32 
 33         public ObservableCollection<ClassesInfo> Classes
 34         {
 35             get { return classes; }
 36             set { SetProperty(ref classes, value); }
 37         }
 38 
 39         private IDialogService dialogService;
 40 
 41         public ClassesViewModel(IDialogService dialogService)
 42         {
 43             this.dialogService = dialogService;
 44             this.pageNum = 1;
 45             this.pageSize = 20;
 46         }
 47 
 48         private void InitInfo()
 49         {
 50             Classes = new ObservableCollection<ClassesInfo>();
 51             var pagedRequst = ClassesHttpUtil.GetClassess(this.Dept,this.Grade, this.pageNum, this.pageSize);
 52             var entities = pagedRequst.items;
 53             Classes.AddRange(entities.Select(r=>new ClassesInfo(r)));
 54             //
 55             this.TotalCount = pagedRequst.count;
 56             this.TotalPage = ((int)Math.Ceiling(this.TotalCount * 1.0 / this.pageSize));
 57         }
 58 
 59         #endregion
 60 
 61         #region event
 62 
 63         private DelegateCommand loadedCommand;
 64 
 65         public DelegateCommand LoadedCommand
 66         {
 67             get
 68             {
 69                 if (loadedCommand == null)
 70                 {
 71                     loadedCommand = new DelegateCommand(Loaded);
 72                 }
 73                 return loadedCommand;
 74             }
 75         }
 76 
 77         private void Loaded()
 78         {
 79             InitInfo();
 80         }
 81 
 82         private DelegateCommand queryCommand;
 83 
 84         public DelegateCommand QueryCommand
 85         {
 86             get
 87             {
 88                 if (queryCommand == null)
 89                 {
 90                     queryCommand = new DelegateCommand(Query);
 91                 }
 92                 return queryCommand;
 93             }
 94         }
 95 
 96         private void Query() { 
 97             this.pageNum = 1;
 98             this.InitInfo();
 99         }
100 
101         /// <summary>
102         /// new command
103         /// </summary>
104         private DelegateCommand addCommand;
105 
106         public DelegateCommand AddCommand
107         {
108             get
109             {
110                 if (addCommand == null)
111                 {
112                     addCommand = new DelegateCommand(Add);
113                 }
114                 return addCommand;
115             }
116         }
117 
118         private void Add()
119         {
120             this.dialogService.ShowDialog("addEditClasses",null, AddEditCallBack, "MetroDialogWindow");
121         }
122 
123         private void AddEditCallBack(IDialogResult dialogResult) {
124             if (dialogResult != null && dialogResult.Result == ButtonResult.OK) {
125                 //refresh the list
126                 this.pageNum = 1;
127                 this.InitInfo();
128             }
129         }
130 
131         /// <summary>
132         /// edit command
133         /// </summary>
134         private DelegateCommand<object> editCommand;
135 
136         public DelegateCommand<object> EditCommand
137         {
138             get
139             {
140                 if (editCommand == null)
141                 {
142                     editCommand = new DelegateCommand<object>(Edit);
143                 }
144                 return editCommand;
145             }
146         }
147 
148         private void Edit(object obj)
149         {
150             if (obj == null) {
151                 return;
152             }
153             var Id = int.Parse(obj.ToString());
154             var classes = this.Classes.FirstOrDefault(r => r.Id == Id);
155             if (classes == null)
156             {
157                 MessageBox.Show("invalid class ID");
158                 return;
159             }
160             if (MessageBoxResult.Yes != MessageBox.Show("Are you sure to delete?", "Confirm", MessageBoxButton.YesNo))
161             {
162                 return;
163             }
164             IDialogParameters dialogParameters = new DialogParameters();
165             dialogParameters.Add("classes",classes);
166             this.dialogService.ShowDialog("addEditClasses", dialogParameters, AddEditCallBack, "MetroDialogWindow");
167         }
168 
169         /// <summary>
170         /// edit command
171         /// </summary>
172         private DelegateCommand<object> deleteCommand;
173 
174         public DelegateCommand<object> DeleteCommand
175         {
176             get
177             {
178                 if (deleteCommand == null)
179                 {
180                     deleteCommand = new DelegateCommand<object>(Delete);
181                 }
182                 return deleteCommand;
183             }
184         }
185 
186         private void Delete(object obj)
187         {
188             if (obj == null)
189             {
190                 return;
191             }
192             var Id = int.Parse(obj.ToString());
193             var classes = this.Classes.FirstOrDefault(r => r.Id == Id);
194             if (classes == null)
195             {
196                 MessageBox.Show("invalid class ID");
197                 return;
198             }
199             bool flag = ClassesHttpUtil.DeleteClasses(Id);
200             if (flag) {
201                 this.pageNum = 1;
202                 this.InitInfo();
203             }
204         }
205 
206         #endregion
207 
208     }
209 }

The AddEditClassesViewModel code is also divided into three parts:

  1. Properties and constructors, mainly used for data binding, such as page text boxes, drop-down selection boxes, etc.
  2. Command Command, mainly used to respond to events, such as save, cancel, etc.
  3. Dialog interface, because the new editor is presented in the form of a pop-up box, so according to the requirements of the Prism framework, the IDialogAware interface needs to be implemented.

The specific code of AddEditClassesViewModel is as follows:

  1 namespace SIMS.ClassesModule.ViewModels
  2 {
  3     public class AddEditClassesViewModel : BindableBase, IDialogAware
  4     {
  5         #region Properties and Constructors
  6 
  7         /// <summary>
  8         /// class entity
  9         /// </summary>
 10         private ClassesInfo classes;
 11     
 12         public ClassesInfo Classes
 13         {
 14             get { return classes; }
 15             set { SetProperty(ref classes ,value); }
 16         }
 17 
 18         private List<StudentEntity> monitors;
 19 
 20         public List<StudentEntity> Monitors
 21         {
 22             get { return monitors; }
 23             set { SetProperty(ref monitors , value); }
 24         }
 25 
 26         private StudentEntity monitor;
 27 
 28         public StudentEntity Monitor
 29         {
 30             get { return monitor; }
 31             set { SetProperty(ref monitor, value); }
 32         }
 33 
 34         public AddEditClassesViewModel() { 
 35         
 36         }
 37 
 38         #endregion
 39 
 40         #region Command
 41 
 42         private DelegateCommand loadedCommand;
 43 
 44         public DelegateCommand LoadedCommand
 45         {
 46             get
 47             {
 48                 if (loadedCommand == null)
 49                 {
 50                     loadedCommand = new DelegateCommand(Loaded);
 51                 }
 52                 return loadedCommand;
 53             }
 54         }
 55 
 56         private void Loaded()
 57         {
 58             this.Monitors= new List<StudentEntity>();
 59             if (Classes?.Id>0) { 
 60                 var pagedRequst = StudentHttpUtil.GetStudentsByClasses(Classes.Id);
 61                 var entities = pagedRequst.items;
 62                 Monitors.AddRange(entities);
 63                 //If there is a monitor, assign the monitor to the monitor
 64                 if (Classes.Monitor > 0) { 
 65                     this.Monitor= this.Monitors?.FirstOrDefault(r=>r.Id==Classes.Monitor);
 66                 }
 67             }
 68             
 69         }
 70 
 71         private DelegateCommand cancelCommand;
 72 
 73         public DelegateCommand CancelCommand
 74         {
 75             get
 76             {
 77                 if (cancelCommand == null)
 78                 {
 79                     cancelCommand = new DelegateCommand(Cancel);
 80                 }
 81                 return cancelCommand;
 82             }
 83         }
 84 
 85         private void Cancel()
 86         {
 87             RequestClose?.Invoke((new DialogResult(ButtonResult.Cancel)));
 88         }
 89 
 90         private DelegateCommand  saveCommand;
 91 
 92         public DelegateCommand SaveCommand
 93         {
 94             get
 95             {
 96                 if (saveCommand == null)
 97                 {
 98                     saveCommand = new DelegateCommand(Save);
 99                 }
100                 return saveCommand;
101             }
102         }
103 
104         private void Save() {
105             if (Classes != null) {
106                 Classes.CreateTime = DateTime.Now;
107                 Classes.LastEditTime = DateTime.Now;
108                 if (Monitor != null) {
109                     Classes.Monitor = Monitor.Id;
110                 }
111                 bool flag=false;
112                 if (Classes.Id > 0) {
113                    flag = ClassesHttpUtil.UpdateClasses(Classes);
114                 }
115                 else { 
116                    flag = ClassesHttpUtil.AddClasses(Classes);
117                 }
118                 if (flag)
119                 {
120                     RequestClose?.Invoke((new DialogResult(ButtonResult.OK)));
121                 }
122             }
123         }
124 
125 
126         #endregion
127 
128         #region dialog
129 
130         public string Title =>  "Add or edit class information";
131 
132         public event Action<IDialogResult> RequestClose;
133 
134         public bool CanCloseDialog()
135         {
136             return true;
137         }
138 
139         public void OnDialogClosed()
140         {
141             
142         }
143 
144         public void OnDialogOpened(IDialogParameters parameters)
145         {
146             if (parameters != null && parameters.ContainsKey("classes"))
147             {
148                 this.Classes = parameters.GetValue<ClassesInfo>("classes");
149             }
150             else { 
151                 this.Classes = new ClassesInfo();
152             }
153         }
154 
155         #endregion
156 
157     }
158 }

4. Sample screenshot

A screenshot of the class management example is shown below:

 

student management

1. Interface access class StudentHttpUtil

The student data table structure and service interface have been introduced in the second article. If you have any questions, you can go to the reference. The interface access class is used to encapsulate the interface provided by the access server. As follows:

 1 namespace SIMS.Utils.Http
 2 {
 3     /// <summary>
 4     /// student class Http Access generic classes
 5     /// </summary>
 6     public class StudentHttpUtil:HttpUtil
 7     {
 8         /// <summary>
 9         /// pass id Inquire about student information
10         /// </summary>
11         /// <param name="id"></param>
12         /// <returns></returns>
13         public static StudentEntity GetStudent(int id)
14         {
15             Dictionary<string, object> data = new Dictionary<string, object>();
16             data["id"] = id;
17             var str = Get(UrlConfig.STUDENT_GETSTUDENT, data);
18             var student = StrToObject<StudentEntity>(str);
19             return student;
20         }
21 
22         public static PagedRequest<StudentEntity> GetStudents(string no,string name, int pageNum, int pageSize) {
23             Dictionary<string, object> data = new Dictionary<string, object>();
24             data["no"] = no;
25             data["name"] = name;
26             data["pageNum"] = pageNum;
27             data["pageSize"] = pageSize;
28             var str = Get(UrlConfig.STUDENT_GETSTUDENTS, data);
29             var students = StrToObject<PagedRequest<StudentEntity>>(str);
30             return students;
31         }
32 
33         public static PagedRequest<StudentEntity> GetStudentsByClasses(int classId)
34         {
35             Dictionary<string, object> data = new Dictionary<string, object>();
36             data["classId"] = classId;
37             var str = Get(UrlConfig.STUDENT_GETSTUDENTSBYCLASSES, data);
38             var students = StrToObject<PagedRequest<StudentEntity>>(str);
39             return students;
40         }
41 
42         public static bool AddStudent(StudentEntity student)
43         {
44             var ret = Post<StudentEntity>(UrlConfig.STUDENT_ADDSTUDENT, student);
45             return int.Parse(ret) == 0;
46         }
47 
48         public static bool UpdateStudent(StudentEntity student)
49         {
50             var ret = Put<StudentEntity>(UrlConfig.STUDENT_UPDATESTUDENT, student);
51             return int.Parse(ret) == 0;
52         }
53 
54         public static bool DeleteStudent(int Id)
55         {
56             Dictionary<string, string> data = new Dictionary<string, string>();
57             data["Id"] = Id.ToString();
58             var ret = Delete(UrlConfig.STUDENT_DELETESTUDENT, data);
59             return int.Parse(ret) == 0;
60         }
61     }
62 }

2. Client page view

The client view page of the student management module is also divided into two: student list query, and a new page for editing student information.

Student List Inquiry Page

The design of knowledge points on the student information list page is similar to that of class management, with only one difference:

  1. In the database, gender is stored in bit type. In C#, the data type is bool, but it needs to be converted to male or female display in the list, so Converter needs to be used for conversion.

Student information query page, the specific code is as follows:

  1 <UserControl x:Class="SIMS.StudentModule.Views.Student"
  2       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4       xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  5       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  6       xmlns:local="clr-namespace:SIMS.StudentModule.Views"
  7       xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
  8       xmlns:mahApps ="http://metro.mahapps.com/winfx/xaml/controls"
  9       xmlns:prism="http://prismlibrary.com/"      
 10       xmlns:ctrls ="clr-namespace:SIMS.Utils.Controls;assembly=SIMS.Utils"
 11       xmlns:conv="clr-namespace:SIMS.Utils.Converter;assembly=SIMS.Utils"
 12       mc:Ignorable="d" 
 13       prism:ViewModelLocator.AutoWireViewModel="True"
 14       d:DesignHeight="450" d:DesignWidth="800">
 15     
 16     <UserControl.Resources>
 17         <ResourceDictionary>
 18             <ResourceDictionary.MergedDictionaries>
 19                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
 20                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
 21                 <ResourceDictionary>
 22                     <conv:SexConverter x:Key="SexConverter"></conv:SexConverter>
 23                     <Style x:Key="LinkButton" TargetType="Button">
 24                         <Setter Property="Background" Value="White"></Setter>
 25                         <Setter Property="Cursor" Value="Hand"></Setter>
 26                         <Setter Property="Margin" Value="3"></Setter>
 27                         <Setter Property="MinWidth" Value="80"></Setter>
 28                         <Setter Property="MinHeight" Value="25"></Setter>
 29                         <Setter Property="BorderThickness" Value="0 0 0 0"></Setter>
 30                     </Style>
 31                 </ResourceDictionary>
 32             </ResourceDictionary.MergedDictionaries>
 33         </ResourceDictionary>
 34     </UserControl.Resources>
 35     <i:Interaction.Triggers>
 36         <i:EventTrigger EventName="Loaded">
 37             <i:InvokeCommandAction Command="{Binding LoadedCommand}"></i:InvokeCommandAction>
 38         </i:EventTrigger>
 39     </i:Interaction.Triggers>
 40     <Grid>
 41         <Grid.RowDefinitions>
 42             <RowDefinition Height="Auto"></RowDefinition>
 43             <RowDefinition Height="Auto"></RowDefinition>
 44             <RowDefinition Height="*"></RowDefinition>
 45             <RowDefinition Height="Auto"></RowDefinition>
 46         </Grid.RowDefinitions>
 47         <TextBlock Text="student information" FontSize="20" Background="AliceBlue" Margin="2"></TextBlock>
 48         <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
 49             <TextBlock Text="student ID" VerticalAlignment="Center" Margin="2"></TextBlock>
 50             <TextBox Margin="4" MinWidth="120" Height="30"
 51                      Text="{Binding No}"
 52                              HorizontalContentAlignment="Stretch"
 53                              mahApps:TextBoxHelper.ClearTextButton="True"
 54                              mahApps:TextBoxHelper.Watermark="student ID"
 55                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 56                              SpellCheck.IsEnabled="True" />
 57             <TextBlock Text="Name" VerticalAlignment="Center" Margin="2"></TextBlock>
 58             <TextBox Margin="4" MinWidth="120" Height="30"
 59                      Text="{Binding Name}"
 60                              HorizontalContentAlignment="Stretch"
 61                              mahApps:TextBoxHelper.ClearTextButton="True"
 62                              mahApps:TextBoxHelper.Watermark="student name"
 63                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 64                              SpellCheck.IsEnabled="True" />
 65             <Button Content="Inquire" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding QueryCommand}"></Button>
 66             <Button Content="new" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding AddCommand}"></Button>
 67         </StackPanel>
 68         <DataGrid x:Name="dgStudent"
 69                   Grid.Row="2"
 70                   Grid.Column="0"
 71                   Margin="2"
 72                   AutoGenerateColumns="False"
 73                   CanUserAddRows="False"
 74                   CanUserDeleteRows="False"
 75                   ItemsSource="{Binding Students}"
 76                   RowHeaderWidth="0">
 77             <DataGrid.Columns>
 78                 <DataGridTextColumn Binding="{Binding No}" Header="student ID" Width="*" />
 79                 <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"/>
 80                 <DataGridTextColumn Binding="{Binding Age}" Header="age" Width="*"/>
 81                 <DataGridTextColumn Binding="{Binding Sex, Converter={StaticResource SexConverter}}" Header="gender" Width="*"/>
 82                 <DataGridTextColumn Binding="{Binding ClassesName}" Header="class" Width="*" />
 83                 <DataGridTemplateColumn Header="operate" Width="*">
 84                     <DataGridTemplateColumn.CellTemplate>
 85                         <DataTemplate>
 86                             <StackPanel Orientation="Horizontal">
 87                                 <Button Content="Edit" Style="{StaticResource LinkButton}" Command="{Binding RelativeSource={RelativeSource  AncestorType=DataGrid,  Mode=FindAncestor}, Path=DataContext.EditCommand}" CommandParameter="{Binding Id}"  >
 88                                     <Button.Template>
 89                                         <ControlTemplate TargetType="Button">
 90                                             <TextBlock TextDecorations="Underline" HorizontalAlignment="Center">
 91                                                 <ContentPresenter />
 92                                             </TextBlock>
 93                                         </ControlTemplate>
 94                                     </Button.Template>
 95                                 </Button>
 96                                 <Button Content="Delete" Style="{StaticResource LinkButton}" Command="{Binding RelativeSource={RelativeSource  AncestorType=DataGrid,  Mode=FindAncestor}, Path=DataContext.DeleteCommand}" CommandParameter="{Binding Id}">
 97                                     <Button.Template>
 98                                         <ControlTemplate TargetType="Button">
 99                                             <TextBlock TextDecorations="Underline" HorizontalAlignment="Center">
100                                                 <ContentPresenter />
101                                             </TextBlock>
102                                         </ControlTemplate>
103                                     </Button.Template>
104                                 </Button>
105                             </StackPanel>
106                         </DataTemplate>
107                     </DataGridTemplateColumn.CellTemplate>
108                 </DataGridTemplateColumn>
109             </DataGrid.Columns>
110         </DataGrid>
111         <ctrls:PageControl Grid.Row="3" DataContext="{Binding}" ></ctrls:PageControl>
112     </Grid>
113 </UserControl>

Add edit page

The knowledge points involved in the new edit page are similar to the new page in the class, with only one difference:

  1. The bool type in C# needs to be bound to two radio buttons to represent male and female, so it needs to be extended.

Add an edit page, the specific code is as follows:

 1 <UserControl x:Class="SIMS.StudentModule.Views.AddEditStudent"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:local="clr-namespace:SIMS.StudentModule.Views"
 7              xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
 8              xmlns:mahApps ="http://metro.mahapps.com/winfx/xaml/controls"
 9              xmlns:prism="http://prismlibrary.com/"      
10              mc:Ignorable="d" 
11              d:DesignHeight="450" d:DesignWidth="600">
12     <prism:Dialog.WindowStyle>
13         <Style TargetType="Window">
14             <Setter Property="Width" Value="600"></Setter>
15             <Setter Property="Height" Value="400"></Setter>
16         </Style>
17     </prism:Dialog.WindowStyle>
18     <UserControl.Resources>
19         <ResourceDictionary>
20             <ResourceDictionary.MergedDictionaries>
21                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
22                 <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
23             </ResourceDictionary.MergedDictionaries>
24         </ResourceDictionary>
25     </UserControl.Resources>
26     <i:Interaction.Triggers>
27         <i:EventTrigger EventName="Loaded">
28             <i:InvokeCommandAction Command="{Binding LoadedCommand}"></i:InvokeCommandAction>
29         </i:EventTrigger>
30     </i:Interaction.Triggers>
31     <Grid>
32         <Grid.ColumnDefinitions>
33             <ColumnDefinition Width="0.2*"></ColumnDefinition>
34             <ColumnDefinition Width="Auto"></ColumnDefinition>
35             <ColumnDefinition Width="*"></ColumnDefinition>
36             <ColumnDefinition Width="0.2*"></ColumnDefinition>
37         </Grid.ColumnDefinitions>
38         <Grid.RowDefinitions>
39             <RowDefinition></RowDefinition>
40             <RowDefinition></RowDefinition>
41             <RowDefinition></RowDefinition>
42             <RowDefinition></RowDefinition>
43             <RowDefinition></RowDefinition>
44             <RowDefinition></RowDefinition>
45         </Grid.RowDefinitions>
46 
47 
48         <TextBlock Text="student ID" Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="3"></TextBlock>
49         <TextBox Grid.Row="0" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Student.No}"></TextBox>
50         <TextBlock Text="Name" Grid.Row="1" Grid.Column="1"  VerticalAlignment="Center" Margin="3"></TextBlock>
51         <TextBox Grid.Row="1" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Student.Name}"></TextBox>
52         <TextBlock Text="age" Grid.Row="2" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
53         <TextBox Grid.Row="2" Grid.Column="2" MinWidth="120" Height="35"   VerticalAlignment="Center" Margin="3" Text="{Binding Student.Age}"></TextBox>
54         <TextBlock Text="gender" Grid.Row="3" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
55         <StackPanel Grid.Row="3" Grid.Column="2" Orientation="Horizontal" >
56             <RadioButton Content="male" IsChecked="{Binding Student.IsBoy}"></RadioButton>
57             <RadioButton Content="Female" IsChecked="{Binding Student.IsGirl}"></RadioButton>
58         </StackPanel>
59         
60         <TextBlock Text="class" Grid.Row="4" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
61         <ComboBox Grid.Row="4" Grid.Column="2" MinWidth="120" Height="35" ItemsSource="{Binding Classess}" mahApps:TextBoxHelper.ClearTextButton="True" SelectedItem="{Binding Classes}">
62             <ComboBox.ItemTemplate>
63                 <DataTemplate>
64                     <StackPanel Orientation="Horizontal">
65                         <TextBlock Text="{Binding Dept}"></TextBlock>
66                         <TextBlock Text="{Binding Grade}"></TextBlock>
67                         <TextBlock Text="{Binding Name}"></TextBlock>
68                     </StackPanel>
69                 </DataTemplate>
70             </ComboBox.ItemTemplate>
71         </ComboBox>
72         <StackPanel Grid.Row="5" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center" Margin="3">
73             <Button Content="Cancel" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding CancelCommand}" ></Button>
74             <Button Content="save" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding SaveCommand}"></Button>
75         </StackPanel>
76     </Grid>
77 </UserControl>

3. Client ViewModel

The student manages the client-side ViewModel, which corresponds to the page view and is also divided into two parts

The StudentViewModel code is divided into three parts:

  1. Properties and constructors, mainly used for data binding, such as query conditions, lists, etc. All properties are assigned using SetProperty.
  2. Command Command, such as query, add, edit, delete commands, etc. All commands can be defined as DelegateCommand type.
  3. The paging part is omitted here because the paging function code is similar.

The specific code of StudentViewModel is as follows:

  1 namespace SIMS.StudentModule.ViewModels
  2 {
  3     public class StudentViewModel:BindableBase
  4     {
  5         #region Properties and Constructors
  6 
  7         /// <summary>
  8         /// student ID
  9         /// </summary>
 10         private string no;
 11 
 12         public string No
 13         {
 14             get { return no; }
 15             set { SetProperty(ref no , value); }
 16         }
 17 
 18         /// <summary>
 19         /// student name
 20         /// </summary>
 21         private string name;
 22 
 23         public string Name
 24         {
 25             get { return name; }
 26             set { SetProperty(ref name, value); }
 27         }
 28 
 29         private ObservableCollection<StudentInfo> students;
 30 
 31         public ObservableCollection<StudentInfo> Students
 32         {
 33             get { return students; }
 34             set { SetProperty(ref students, value); }
 35         }
 36 
 37         private IDialogService dialogService;
 38 
 39         public StudentViewModel(IDialogService dialogService) {
 40             this.dialogService = dialogService;
 41             this.pageNum = 1;
 42             this.pageSize = 20;
 43         }
 44 
 45         private void InitInfo() {
 46             Students = new ObservableCollection<StudentInfo>();
 47             var pagedRequst = StudentHttpUtil.GetStudents(this.No,this.Name, this.pageNum, this.pageSize);
 48             var entities = pagedRequst.items;
 49             Students.AddRange(entities.Select(r=>new StudentInfo(r)));
 50             //
 51             this.TotalCount = pagedRequst.count;
 52             this.TotalPage=((int)Math.Ceiling(this.TotalCount*1.0/this.pageSize));
 53         }
 54 
 55         #endregion
 56 
 57         #region event
 58 
 59         private DelegateCommand loadedCommand;
 60 
 61         public DelegateCommand LoadedCommand
 62         {
 63             get
 64             {
 65                 if (loadedCommand == null)
 66                 {
 67                     loadedCommand = new DelegateCommand(Loaded);
 68                 }
 69                 return loadedCommand;
 70             }
 71         }
 72 
 73         private void Loaded()
 74         {
 75             InitInfo();
 76         }
 77 
 78         /// <summary>
 79         /// new command
 80         /// </summary>
 81         private DelegateCommand addCommand;
 82 
 83         public DelegateCommand AddCommand
 84         {
 85             get
 86             {
 87                 if (addCommand == null)
 88                 {
 89                     addCommand = new DelegateCommand(Add);
 90                 }
 91                 return addCommand;
 92             }
 93         }
 94 
 95         private void Add()
 96         {
 97             this.dialogService.ShowDialog("addEditStudent", null, AddEditCallBack, "MetroDialogWindow");
 98         }
 99 
100         private void AddEditCallBack(IDialogResult dialogResult)
101         {
102             if (dialogResult != null && dialogResult.Result == ButtonResult.OK)
103             {
104                 //refresh the list
105                 this.pageNum = 1;
106                 this.InitInfo();
107             }
108         }
109 
110         /// <summary>
111         /// edit command
112         /// </summary>
113         private DelegateCommand<object> editCommand;
114 
115         public DelegateCommand<object> EditCommand
116         {
117             get
118             {
119                 if (editCommand == null)
120                 {
121                     editCommand = new DelegateCommand<object>(Edit);
122                 }
123                 return editCommand;
124             }
125         }
126 
127         private void Edit(object obj) {
128             if (obj == null)
129             {
130                 return;
131             }
132             var Id = int.Parse(obj.ToString());
133             var student = this.Students.FirstOrDefault(r => r.Id == Id);
134             if (student == null)
135             {
136                 MessageBox.Show("invalid student ID");
137                 return;
138             }
139             if (MessageBoxResult.Yes != MessageBox.Show("Are you sure to delete?", "Confirm", MessageBoxButton.YesNo))
140             {
141                 return;
142             }
143             IDialogParameters dialogParameters = new DialogParameters();
144             dialogParameters.Add("student", student);
145             this.dialogService.ShowDialog("addEditStudent", dialogParameters, AddEditCallBack, "MetroDialogWindow");
146         }
147 
148         /// <summary>
149         /// edit command
150         /// </summary>
151         private DelegateCommand<object> deleteCommand;
152 
153         public DelegateCommand<object> DeleteCommand
154         {
155             get
156             {
157                 if (deleteCommand == null)
158                 {
159                     deleteCommand = new DelegateCommand<object>(Delete);
160                 }
161                 return deleteCommand;
162             }
163         }
164 
165         private void Delete(object obj)
166         {
167             if (obj == null)
168             {
169                 return;
170             }
171             var Id = int.Parse(obj.ToString());
172             var classes = this.Students.FirstOrDefault(r => r.Id == Id);
173             if (classes == null)
174             {
175                 MessageBox.Show("invalid student ID");
176                 return;
177             }
178             bool flag = StudentHttpUtil.DeleteStudent(Id);
179             if (flag)
180             {
181                 this.pageNum = 1;
182                 this.InitInfo();
183             }
184         }
185 
186         #endregion
187 
188     }
189 }

The AddEditStudentViewModel code is also divided into three parts:

  1. Properties and constructors, mainly used for data binding, such as page text boxes, drop-down selection boxes, etc.
  2. Command Command, mainly used to respond to events, such as save, cancel, etc.
  3. Dialog interface, because the new editor is presented in the form of a pop-up box, so according to the requirements of the Prism framework, the IDialogAware interface needs to be implemented. (The implementation of the interface code is similar and omitted here)

The specific code of AddEditStudentViewModel is as follows:

  1 namespace SIMS.StudentModule.ViewModels
  2 {
  3     public class AddEditStudentViewModel : BindableBase, IDialogAware
  4     {
  5 
  6         /// <summary>
  7         /// class entity
  8         /// </summary>
  9         private ClassesEntity classes;
 10 
 11         public ClassesEntity Classes
 12         {
 13             get { return classes; }
 14             set { SetProperty(ref classes, value); }
 15         }
 16 
 17         /// <summary>
 18         /// class list
 19         /// </summary>
 20         private List<ClassesEntity> classess;
 21 
 22         public List<ClassesEntity> Classess
 23         {
 24             get { return classess; }
 25             set { SetProperty(ref classess, value); }
 26         }
 27 
 28         private StudentInfo student;
 29 
 30         public StudentInfo Student
 31         {
 32             get { return student; }
 33             set { student = value; }
 34         }
 35 
 36         public AddEditStudentViewModel() { 
 37         
 38         }
 39 
 40         #region Command
 41 
 42         private DelegateCommand loadedCommand;
 43 
 44         public DelegateCommand LoadedCommand
 45         {
 46             get
 47             {
 48                 if (loadedCommand == null)
 49                 {
 50                     loadedCommand = new DelegateCommand(Loaded);
 51                 }
 52                 return loadedCommand;
 53             }
 54         }
 55 
 56         private void Loaded()
 57         {
 58             this.Classess = new List<ClassesEntity>();
 59             var pagedRequst = ClassesHttpUtil.GetClassess(null,null,1,0);//0 means all classes
 60             var entities = pagedRequst.items;
 61             Classess.AddRange(entities);
 62         }
 63 
 64         private DelegateCommand cancelCommand;
 65 
 66         public DelegateCommand CancelCommand
 67         {
 68             get
 69             {
 70                 if (cancelCommand == null)
 71                 {
 72                     cancelCommand = new DelegateCommand(Cancel);
 73                 }
 74                 return cancelCommand;
 75             }
 76         }
 77 
 78         private void Cancel() {
 79             RequestClose?.Invoke((new DialogResult(ButtonResult.Cancel)));
 80         }
 81 
 82         private DelegateCommand saveCommand;
 83 
 84         public DelegateCommand SaveCommand
 85         {
 86             get
 87             {
 88                 if (saveCommand == null)
 89                 {
 90                     saveCommand = new DelegateCommand(Save);
 91                 }
 92                 return saveCommand;
 93             }
 94         }
 95 
 96         private void Save()
 97         {
 98             if (Student != null)
 99             {
100                 Student.CreateTime = DateTime.Now;
101                 Student.LastEditTime = DateTime.Now;
102                 bool flag = false;
103                 if (Classes != null) { 
104                     Student.ClassesId = Classes.Id;
105                 }
106                 if (Student.Id > 0)
107                 {
108                     flag = StudentHttpUtil.UpdateStudent(Student);
109                 }
110                 else
111                 {
112                     flag = StudentHttpUtil.AddStudent(Student);
113                 }
114                 if (flag)
115                 {
116                     RequestClose?.Invoke((new DialogResult(ButtonResult.OK)));
117                 }
118             }
119         }
120 
121         #endregion
122     }
123 }

4. Sample screenshot

A screenshot of the student management example is shown below:

Summarize

Through the class management module, student management module of this article, and the course management module in the previous article, it is not difficult to find that the development of each module consists of a list DataGrid, a text box TextBox, a drop-down box Combox, and a radio button. RadioButton, Button Button, etc., although the functions are slightly different, but they are always the same. The development method is also similar, and the complex functions are accumulated by ordinary functions. This is also the gradual arrangement of this series of articles from shallow to deep. I hope to be able to attract others, not limited to a certain function, but to be able to draw inferences from one case, self-understanding, in order to achieve the ability of self-development.

Tags: C# WPF prism

Posted by plugnz on Thu, 02 Jun 2022 08:55:52 +0530