主頁 > .NET開發 > WPF開發學生資訊管理系統【WPF+Prism+MAH+WebApi】(四)

WPF開發學生資訊管理系統【WPF+Prism+MAH+WebApi】(四)

2022-06-02 11:21:48 .NET開發

最近通過WPF開發專案,為了對WPF知識點進行總結,所以利用業余時間,開發一個學生資訊管理系統【Student Information Management System】,前三篇文章進行了框架搭建和模塊劃分,后臺WebApi介面撰寫,以及課程管理模塊開發,本文在前三篇基礎之上,繼續深入開發學生資訊管理系統的班級管理和學生管理模塊,通過本篇文章,將繼續鞏固之前的知識點,本文僅供學習分享使用,如有不足之處,還請指正,

涉及知識點

由于班級管理和學生管理的服務端開發,在第二篇文章中以后介紹,所以本篇專注介紹客戶端功能的開發,涉及知識點如下:

  1. WPF開發中TextBlock,TextBox,DataGrid,Combox等控制元件的基礎使用以及資料系結等操作,
  2. MAH樣式的使用,在本示例中MAH主要用于統一頁面風格,提高用戶體驗,
  3. HttpClient使用,主要用于訪問服務端提供的介面,

業務邏輯

首先班級管理和學生管理既有關聯,又相互獨立,不像課程管理模塊獨立存在,不與其他模塊存在依賴,所以兩個模塊一起放在一篇文章進行講解,關系如下:

  1. 學生屬于某一班級之學生,所以學生中包含班級資訊,
  2. 班級中存在班長,班長又屬于學生的一個物體,

班級管理

1. 介面訪問類ClassesHttpUtil

班級資料表結構和服務介面,在第二篇文章中已有介紹,如有疑問,可前往參考,介面訪問類用于封裝訪問服務端提供的介面,如下所示:

 1 namespace SIMS.Utils.Http
 2 {
 3     public class ClassesHttpUtil:HttpUtil
 4     {
 5         /// <summary>
 6         /// 通過id查詢學生資訊
 7         /// </summary>
 8         /// <param name="id"></param>
 9         /// <returns></returns>
10         public static ClassesEntity GetClasses(int id)
11         {
12             Dictionary<string, object> data = https://www.cnblogs.com/hsiang/archive/2022/06/01/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 = https://www.cnblogs.com/hsiang/archive/2022/06/01/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 = https://www.cnblogs.com/hsiang/archive/2022/06/01/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. 客戶端頁面視圖

班級管理的客戶端頁面視圖共兩個,一個查詢串列頁面,一個新增編輯頁面,共同組成了班級管理的增刪改查,

查詢班級串列頁面,涉及知識點如下所示:

  1. 查詢條件或者串列中資料列展示,通過資料系結Binding的方式與ViewModel進行互動,即點擊查詢按鈕,不再傳遞引數,因為ViewModel中的屬性已經同步更新,
  2. ViewModel中并非所有屬性都可實作雙向系結,必須是實作具有通知功能的屬性才可以,在Prism框架中,通過BindableBase的SetProperty方法可以快速實作,
  3. View視圖中如果控制元件存在Command命令,則可以直接系結,如果不存在,則可以i:Interaction.Triggers將事件轉換為命令,如Load事件等,
  4. 在串列中,如果需要添加按鈕,可以通過DataTemplate進行資料定制,

查詢班級頁面代碼,如下所示:

  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="班級資訊" FontSize="20" Background="AliceBlue" Margin="2"></TextBlock>
 45         <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
 46             <TextBlock Text="專業" 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="專業"
 52                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 53                              SpellCheck.IsEnabled="True" />
 54             <TextBlock Text="年級" 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="年級"
 60                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 61                              SpellCheck.IsEnabled="True" />
 62             <Button Content="查詢" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding QueryCommand}"></Button>
 63             <Button Content="新增" 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="專業" Width="*" />
 76                 <DataGridTextColumn Binding="{Binding Grade}" Header="年級" Width="*"/>
 77                 <DataGridTextColumn Binding="{Binding Name}" Header="班級" Width="*"/>
 78                 <DataGridTextColumn Binding="{Binding HeadTeacher}" Header="班主任" Width="*"/>
 79                 <DataGridTextColumn Binding="{Binding MonitorName}" Header="班長" Width="*" />
 80                 <DataGridTemplateColumn Header="操作" 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>

新增編輯頁面

班級的新增功能和編輯功能,共用一個頁面,涉及知識點如下所示:

  1. 在新增編輯的ViewModel中,班級物體是一個屬性,所以在視圖控制元件中進行資料系結時,需要帶上屬性名,如:Classes.Name ,
  2. 班長串列在新增班級時尚無對應學生,可為空,待維護學生后,可通過學生串列進行選擇即可,
  3. 班長串列為Combox下拉框,系結的是學生物體串列,但客戶端只需看到學生姓名即可,所以需要重寫DataTemplate,只顯示學生姓名,

新增班級資訊視圖,具體代碼如下所示:

 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="專業" 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="年級" 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="班級" 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="班主任" 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="班長" 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="取消" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding CancelCommand}"></Button>
67             <Button Content="保存" 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="注意:新增班級時,班長可空,等維護學生后,再設定班長," Foreground="Red"></TextBlock>
70     </Grid>
71 </UserControl>

3. 客戶端ViewModel

班級管理模塊,ViewModel和視圖對應,也分為查詢串列ViewModel和新增編輯ViewModel,如下所示:

ClassesViewModel頁面代碼分為三部分:

  1. 屬性和建構式,主要用于資料系結,如查詢條件,串列等,所有屬性的set賦值時,均采用SetProperty進行賦值,
  2. 命令Command,如查詢,新增,編輯,洗掉命令等,所有命令可以定義成DelegateCommand型別,
  3. 分頁部分,因分頁功能代碼大同小異,所以此處略去,

ClassesViewModel具體代碼如下所示:

  1 namespace SIMS.ClassesModule.ViewModels
  2 {
  3     public class ClassesViewModel :BindableBase
  4     {
  5         #region 屬性及建構式
  6 
  7         /// <summary>
  8         /// 專業
  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         /// 年級
 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 事件
 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         /// 新增命令
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                 //重繪串列
126                 this.pageNum = 1;
127                 this.InitInfo();
128             }
129         }
130 
131         /// <summary>
132         /// 編輯命令
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("無效的班級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         /// 編輯命令
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("無效的班級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 }

AddEditClassesViewModel代碼同樣分為三部分:

  1. 屬性和建構式,主要用于資料系結,如頁面文本框,下拉選擇框等,
  2. 命令Command,主要用于回應事件,如保存,取消等,
  3. 對話框介面,因為新增編輯是以彈出框的形式呈現,所以根據Prism框架的 要求,需要實作IDialogAware介面,

AddEditClassesViewModel具體代碼如下所示:

  1 namespace SIMS.ClassesModule.ViewModels
  2 {
  3     public class AddEditClassesViewModel : BindableBase, IDialogAware
  4     {
  5         #region 屬性和建構式
  6 
  7         /// <summary>
  8         /// 班級物體
  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                 //如果有班長,則為班長賦值
 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 對話框
129 
130         public string Title =>  "新增或編輯班級資訊";
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. 示例截圖

班級管理示例截圖,如下所示:

 

學生管理

1. 介面訪問類StudentHttpUtil

學生資料表結構和服務介面,在第二篇文章中已有介紹,如有疑問,可前往參考,介面訪問類用于封裝訪問服務端提供的介面,如下所示:

 1 namespace SIMS.Utils.Http
 2 {
 3     /// <summary>
 4     /// 學生類Http訪問通用類
 5     /// </summary>
 6     public class StudentHttpUtil:HttpUtil
 7     {
 8         /// <summary>
 9         /// 通過id查詢學生資訊
10         /// </summary>
11         /// <param name="id"></param>
12         /// <returns></returns>
13         public static StudentEntity GetStudent(int id)
14         {
15             Dictionary<string, object> data = https://www.cnblogs.com/hsiang/archive/2022/06/01/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 = https://www.cnblogs.com/hsiang/archive/2022/06/01/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 = https://www.cnblogs.com/hsiang/archive/2022/06/01/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 = https://www.cnblogs.com/hsiang/archive/2022/06/01/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. 客戶端頁面視圖

學生管理模塊的客戶端視圖頁面,也分為兩個:學生串列查詢,新增編輯學生資訊頁面,

學生串列查詢頁面

學生資訊串列頁面設計知識點,和班級管理差不多,只有一點差異:

  1. 在資料庫中,性別保存的是bit型別,在C#中,資料型別為bool,但是在串列中需要轉換成男或女顯示,所以需要用到Converter進行轉換,

學生資訊查詢頁面,具體代碼如下所示:

  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="學生資訊" FontSize="20" Background="AliceBlue" Margin="2"></TextBlock>
 48         <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
 49             <TextBlock Text="學號" 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="學號"
 55                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 56                              SpellCheck.IsEnabled="True" />
 57             <TextBlock Text="姓名" 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="學生姓名"
 63                              mahApps:TextBoxHelper.WatermarkAlignment="Left"
 64                              SpellCheck.IsEnabled="True" />
 65             <Button Content="查詢" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Width="120" Height="30" Margin="3" Command="{Binding QueryCommand}"></Button>
 66             <Button Content="新增" 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="學號" Width="*" />
 79                 <DataGridTextColumn Binding="{Binding Name}" Header="姓名" Width="*"/>
 80                 <DataGridTextColumn Binding="{Binding Age}" Header="年齡" Width="*"/>
 81                 <DataGridTextColumn Binding="{Binding Sex, Converter={StaticResource SexConverter}}" Header="性別" Width="*"/>
 82                 <DataGridTextColumn Binding="{Binding ClassesName}" Header="班級" Width="*" />
 83                 <DataGridTemplateColumn Header="操作" 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>

新增編輯頁面

新增編輯頁面涉及知識點和班級新增頁面差不多,僅有一處差異:

  1. C#中的bool型別,需要系結到兩個單選按鈕上,以表示男,女,所以需要擴展,

新增編輯頁面,具體代碼如下所示:

 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="學號" 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="姓名" 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="年齡" 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="性別" Grid.Row="3" Grid.Column="1"   VerticalAlignment="Center" Margin="3"></TextBlock>
55         <StackPanel Grid.Row="3" Grid.Column="2" Orientation="Horizontal" >
56             <RadioButton Content="男" IsChecked="{Binding Student.IsBoy}"></RadioButton>
57             <RadioButton Content="女" IsChecked="{Binding Student.IsGirl}"></RadioButton>
58         </StackPanel>
59         
60         <TextBlock Text="班級" 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="取消" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding CancelCommand}" ></Button>
74             <Button Content="保存" Margin="5" MinWidth="120" Height="35" Style="{DynamicResource MahApps.Styles.Button.Square.Accent}" Command="{Binding SaveCommand}"></Button>
75         </StackPanel>
76     </Grid>
77 </UserControl>

3. 客戶端ViewModel

學生管理客戶端ViewModel,與頁面視圖對應,也分為兩個部分

StudentViewModel代碼分為三部分:

  1. 屬性和建構式,主要用于資料系結,如查詢條件,串列等,所有屬性的set賦值時,均采用SetProperty進行賦值,
  2. 命令Command,如查詢,新增,編輯,洗掉命令等,所有命令可以定義成DelegateCommand型別,
  3. 分頁部分,因分頁功能代碼大同小異,所以此處略去,

StudentViewModel具體代碼如下所示:

  1 namespace SIMS.StudentModule.ViewModels
  2 {
  3     public class StudentViewModel:BindableBase
  4     {
  5         #region 屬性及建構式
  6 
  7         /// <summary>
  8         /// 學號
  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         /// 學生姓名
 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 事件
 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         /// 新增命令
 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                 //重繪串列
105                 this.pageNum = 1;
106                 this.InitInfo();
107             }
108         }
109 
110         /// <summary>
111         /// 編輯命令
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("無效的學生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         /// 編輯命令
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("無效的學生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 }

AddEditStudentViewModel代碼同樣分為三部分:

  1. 屬性和建構式,主要用于資料系結,如頁面文本框,下拉選擇框等,
  2. 命令Command,主要用于回應事件,如保存,取消等,
  3. 對話框介面,因為新增編輯是以彈出框的形式呈現,所以根據Prism框架的 要求,需要實作IDialogAware介面,(實作介面代碼大同小異,在此略去)

AddEditStudentViewModel具體代碼如下所示:

  1 namespace SIMS.StudentModule.ViewModels
  2 {
  3     public class AddEditStudentViewModel : BindableBase, IDialogAware
  4     {
  5 
  6         /// <summary>
  7         /// 班級物體
  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         /// 班級串列
 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表示所有班級
 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. 示例截圖

學生管理示例截圖,如下所示:

總結

通過本篇文章的班級管理模塊,學生管理模塊,以及上一篇文章中的課程管理模塊,不難發現,每一個模塊的開發都是由串列DataGrid,文本框TextBox,下拉框Combox,單選按鈕RadioButton,按鈕Button等組成的,雖功能略有差異,但總歸萬變不離其宗,開發方法也大同小異,復雜的功能都是普通的功能累加起來的,這也是本系列文章由淺入深的漸進安排,希望能夠拋磚引玉,不局限于某一功能,而是能夠舉一反三,自我理解,以達到自我開發的能力,


作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文著作權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段宣告,且在文章頁面明顯位置給出原文連接,謝謝,
關注個人公眾號,定時同步更新技術及職場文章

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/484779.html

標籤:.NET技术

上一篇:從我的scss檔案中使用Bootstrap的實用程式API

下一篇:部分折疊的Bootstrap導航欄,隱藏專案不在邊緣

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more