Jenkins (Continuous Integration System with Jenkins)
Hướng dẫn lập trình với SCSF phần II(smart client software factory)
1. Phần II: CHI TIẾT
Tạo Module tên Training.
Reference CABDevExpress.ExtensionKit.dll trong thư mục Lib của solution vào module vừa
tạo.
Chuyển Module vừa tạo sang .Net Framework 4.0.
Các thành phần sử dụng chung cho Module
Khai báo các command
Vào Project Training.Interface của module. Ở thư mục Constants -> Chọn File
CommandNames.cs.
Ở đây có cần tạo ba chức năng Danh mục đào tạo dạng lưới, Danh mục đào tạo dạng ô nhập
liệu, Kế hoạch đào tạo dạng master – detail.
Nên sẽ tạo ra các command như sau
namespace CuscAppFramework.Training.Interface.Constants
{
public class CommandNames : CuscAppFramework.Infrastructure.Interface.Constants.CommandNam
es
{
// Bạn có thể đặt tên tiếng Anh hay tiếng Việt đều được miễn là có ý nghĩa và là chữ
in Hoa
// Command name cho danh mục training version 1 (danh mục dạng lưới)
public const string TRAINING_CATALOG = "TRAINING_CATALOG_CATALOG";
public const string TRAINING_CATALOG_VIEW = "TRAINING_CATALOG_VIEW";
public const string TRAINING_CATALOG_ADD = "TRAINING_CATALOG_ADD";
public const string TRAINING_CATALOG_MODIFY = "TRAINING_CATALOG_MODIFY";
public const string TRAINING_CATALOG_DELETE = "TRAINING_CATALOG_DELETE";
// Command name cho danh mục training version 2 (danh mục dạng ô nhập liệu)
public const string TRAINING_CATALOG_V2 = "TRAINING_CATALOG_V2";
public const string TRAINING_CATALOG_V2_VIEW = "TRAINING_CATALOG_V2_VIEW";
public const string TRAINING_CATALOG_V2_ADD = "TRAINING_CATALOG_V2_ADD";
public const string TRAINING_CATALOG_V2_MODIFY = "TRAINING_CATALOG_V2_MODIFY";
public const string TRAINING_CATALOG_V2_DELETE = "TRAINING_CATALOG_V2_DELETE";
// Command name kế hoạch training (Master - Detail)
public const string TRAINING_PLANS = "TRAINING_PLANS";
public const string TRAINING_PLANS_VIEW = "TRAINING_PLANS_VIEW";
public const string TRAINING_PLANS_ADD = "TRAINING_PLANS_ADD";
public const string TRAINING_PLANS_MODIFY = "TRAINING_PLANS_MODIFY";
public const string TRAINING_PLANS_DELETE = "TRAINING_PLANS_DELETE";
}
}
2. Khai báo các Rule để kiểm tra quyền
Vào Project Training.Interface của module. Ở thư mục Constants -> Add Class Có Tên là
Rules (Tên không thay đổi trên mỗi Module) Theo cấu trúc sau.
namespace CuscAppFramework.Training.Interface.Constants
{
public class Rules
{
/* Bạn có thể đặt tên tiếng Anh hay tiếng Việt đều được miễn là có ý nghĩa và là chữ
in Hoa
* Value của Rule theo cấu trúc <TênModule>.<TênRule>.[<ThaoTác>]<:access>
* Thường bạn nên đặt tên giống với command name cho dễ quản lý.
* Bạn có thể coppy từ command name qua cho nhanh chỉ thay đổi giá trị lại là được.
*/
// Rule cho danh mục training version 1 (danh mục dạng lưới)
public const string TRAINING_CATALOG = "Training.TrainingCatalog:access";
public const string TRAINING_CATALOG_VIEW = "Training.TrainingCatalog.View:access";
public const string TRAINING_CATALOG_ADD = "Training.TrainingCatalog.Add:access";
public const string TRAINING_CATALOG_MODIFY = "Training.TrainingCatalog.Modify:access";
public const string TRAINING_CATALOG_DELETE = "Training.TrainingCatalog.Delete:access";
// Rule cho danh mục training version 2 (danh mục dạng ô nhập liệu)
public const string TRAINING_CATALOG_V2 = "Training.TrainingCatalogV2:access";
public const string TRAINING_CATALOG_V2_VIEW = "Training.TrainingCatalogV2.View:access";
public const string TRAINING_CATALOG_V2_ADD = "Training.TrainingCatalogV2.Add:access";
public const string TRAINING_CATALOG_V2_MODIFY = "Training.TrainingCatalogV2.Modify:access";
public const string TRAINING_CATALOG_V2_DELETE = "Training.TrainingCatalogV2.Delete:access";
// Rule kế hoạch training (Master - Detail)
public const string TRAINING_PLANS = "Training.TrainingPlans:access";
public const string TRAINING_PLANS_VIEW = "Training.TrainingPlans.View:access";
public const string TRAINING_PLANS_ADD = "Training.TrainingPlans.Add:access";
public const string TRAINING_PLANS_MODIFY = "Training.TrainingPlans.Modify:access";
public const string TRAINING_PLANS_DELETE = "Training.TrainingPlans.Delete:access";
}
}
Khai báo các SmartPartInfoName
Vào Project Training.Interface của module. Ở thư mục Constants -> Add Class Có Tên là
SmartPartInfoNames
(Tên không thay đổi trên mỗi Module) theo cấu trúc sau
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CuscAppFramework.Training.Interface.Constants
{
public class SmartPartInfoNames
{
3. // Bạn có thể đặt tên tiếng Anh hay tiếng Việt đều được miễn là có ý nghĩa và là chữ
in Hoa
// SmartPartInfoNames cho danh mục training version 1 (danh mục dạng lưới)
public const string TRAINING_CATALOG = " TRAINING_CATALOG ";
// SmartPartInfoNames cho danh mục training version 2 (danh mục dạng ô nhập liệu)
public const string TRAINING_CATALOG_V2 = "TRAINING_CATALOG_V2";
// SmartPartInfoNames cho kế hoạch training (Master - Detail)
public const string TRAINING_PLANS = "TRAINING_PLANS";
}
}
Thực hiện khai báo quyền trên các chức năng trong databse
Trước tiên vì module Training là module mới
Nên chúng ta sẽ thực hiện thêm module này vào bảng ModuleList
Khai báo các quyền cho chức năng (Tên các quyền này phải giống với tên Rule đã khai báo)
Mở bảng Object trong Database lên sau đó nhập các quyền vào theo hình mô tả sau
4. Gán các quyền vừa khai báo cho vai trò (Role) System. Mở bảng ObjectRole và nhập các
thông tin như hình minh họa sau
Tiếp theo chúng ta sẽ khai báo các Menu cho module Training
Đầu tiên bạn vào file Training.InterfaceConstantsUIExtensionSiteNames.cs
5. Đăng ký menu Cho module Training như sau
namespace CuscAppFramework.Training.Interface.Constants
{
/// <summary>
/// Constants for UI extension site names.
/// </summary>
public class UIExtensionSiteNames : CuscAppFramework.Infrastructure.Interface.Con
stants.UIExtensionSiteNames
{
public const string TrainingMenu = "TrainingMenu";
}
}
Tiếp theo chúng ta vào TrainingTrainingModuleController.cs
Xem Project <TenModule> đã Reference DevExpress.XtraBars.v11.2,
DevExpress.Data.v11.2, DevExpress.XtraGrid.v11.2, DevExpress.XtraEditors.v11.2 và
DevExpress.Utils.v11.2 chưa nếu chưa thì Reference vào
Khai báo sử dụng
using CuscAppFramework.Training.Interface.Constants;
using CuscAppFramework.Infrastructure.Interface.Services;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraBars;
Khai báo menu Training trong Module Controller
Khai báo đoạn code bắt buộc phải có trong Module Controller
#region Phần code bắt buộc phải có của ModuleController dùng để kiểm tra quyền
/// <summary>
/// Kiểm quyền người dùng
/// </summary>
private ISecurityHelper _securityHelper;
[ServiceDependency]
public ISecurityHelper SecurityHelper
{
get { return _securityHelper; }
set { _securityHelper = value; }
}
#endregion Phần code bắt buộc phải có của ModuleController dùng để kiểm tra quyền
Tìm đến hàm ExtendMenu() và khai báo đoạn code như sau
private void ExtendMenu()
{
// Tạo menu Training (Đào tạo)
6. RibbonPage pTraining = new RibbonPage("Đào tạo");
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.TrainingMenu, pTraining);
WorkItem.UIExtensionSites[UIExtensionSiteNames.Ribbon].Add(pTraining);
}
Sau khi khai báo menu tiếp đến chúng ta khai báo các nút cho từng chức năng và add chúng
vào Menu
Vì nút có Icon nên trước tiên ta sẽ thêm các Icon ngày vào Resource
Ở đây đã chuẩn bị sẳn 3 file : TraningCatalog.png, TrainingCatalogV2.png và
TrainingPlans.png
Để thểm vào Resource làm theo hướng dẫn sau:
Right Click vào module cần add Resource -> Chọn Properties-> Chọn Tab Resources
Tại combobox đầu tiên chọn Images, Tiếp tho chọn Add Resource -> chọn Add Existing File-
> chọn File Icon cần load.
Sau khi add Icon vào resources tiếp theo khai báo các button tương ứng với từng chức năng.
Tìm đến hàm ExtendMenu() và khai báo đoạn code như sau
private void ExtendMenu()
{
// Tạo menu Training (Đào tạo)
RibbonPage pTraining = new RibbonPage("Đào tạo");
WorkItem.UIExtensionSites.RegisterSite(UIExtensionSiteNames.TrainingMenu, pTrainin
g);
WorkItem.UIExtensionSites[UIExtensionSiteNames.Ribbon].Add(pTraining);
RibbonPageGroup gTrainingCatalog = new RibbonPageGroup("");
// Kiểm quyền trên danh mục training dạng lưới
if (SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rules.
TRAINING_CATALOG)
|| SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rul
es.TRAINING_CATALOG_VIEW))
{
BarButtonItem btnTrainingCatalog = new BarButtonItem();
btnTrainingCatalog.Caption = "Danh mục đào tạo (dạng lưới)";
btnTrainingCatalog.LargeWidth = 95;
btnTrainingCatalog.RibbonStyle = ((DevExpress.XtraBars.Ribbon.RibbonItemStyles
)(((DevExpress.XtraBars.Ribbon.RibbonItemStyles.Large | DevExpress.XtraBars.Ribbon
.RibbonItemStyles.SmallWithText)| DevExpress.XtraBars.Ribbon.RibbonItemStyles.SmallWithoutText
)));
btnTrainingCatalog.LargeGlyph = global::CuscAppFramework.Training.Properties.R
esources.TraningCatalog;
gTrainingCatalog.ItemLinks.Add(btnTrainingCatalog);
WorkItem.Commands[CommandNames.TRAINING_CATALOG].AddInvoker(btnTrainingCatalog
, "ItemClick");
}
7. // Kiểm quyền trên danh mục training dạng ô nhập liệu
if (SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rules.
TRAINING_CATALOG_V2)
|| SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rul
es.TRAINING_CATALOG_V2_VIEW))
{
BarButtonItem btnTrainingCatalogV2 = new BarButtonItem();
btnTrainingCatalogV2.Caption = "Danh mục đào tạo (ô nhập liệu) ";
btnTrainingCatalogV2.LargeWidth = 105;
btnTrainingCatalogV2.RibbonStyle = ((DevExpress.XtraBars.Ribbon.RibbonItemStyl
es)(((DevExpress.XtraBars.Ribbon.RibbonItemStyles.Large | DevExpress.XtraBars.Ribbon
.RibbonItemStyles.SmallWithText) | DevExpress.XtraBars.Ribbon.RibbonItemStyles.SmallWithoutTex
t)));
btnTrainingCatalogV2.LargeGlyph = global::CuscAppFramework.Training.Properties
.Resources.TrainingCatalogV2;
gTrainingCatalog.ItemLinks.Add(btnTrainingCatalogV2);
WorkItem.Commands[CommandNames.TRAINING_CATALOG_V2].AddInvoker(btnTrainingCata
logV2, "ItemClick");
}
// Kiểm quyền trên kế hoạch đào tạo
if (SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rules.
TRAINING_PLANS)
|| SecurityHelper.Authorized(CuscAppFramework.Training.Interface.Constants.Rul
es.TRAINING_PLANS_VIEW))
{
BarButtonItem btnTrainingPlans = new BarButtonItem();
btnTrainingPlans.Caption = "Kế hoạch đào tạo (Master - Detail)";
btnTrainingPlans.LargeWidth = 105;
btnTrainingPlans.RibbonStyle = ((DevExpress.XtraBars.Ribbon.RibbonItemStyles)
(((DevExpress.XtraBars.Ribbon.RibbonItemStyles.Large | DevExpress.XtraBars.Ribbon.RibbonItemSt
yles.SmallWithText) | DevExpress.XtraBars.Ribbon.RibbonItemStyles.SmallWithoutText)));
btnTrainingPlans.LargeGlyph = global::CuscAppFramework.Training.Properties.Res
ources.TrainingPlans;
gTrainingCatalog.ItemLinks.Add(btnTrainingPlans);
WorkItem.Commands[CommandNames.TRAINING_PLANS].AddInvoker(btnTrainingPlans, "I
temClick");
}
// Thêm group Training Catalog và cấp quyền lên menu
if (gTrainingCatalog.ItemLinks.Count > 0)
{
WorkItem.UIExtensionSites[UIExtensionSiteNames.TrainingMenu].Add(gTrainingCata
log);
}
}
Đến đây khi Debug sẽ thấy menu Đào tạo với các button tương ứng rồi.
Bước tiếp theo là tạo view cho các chức năng
Ở đây để nhanh ta sẽ tạo một loat các View : ViewTrainingCatalog, ViewTrainingCatalogV2,
ViewTrainingPlans với các đoạn code bắt buột cho View và Presenter sau đó sẽ quay lại
code sau.(Cách tạo view xem hướng dẫn phần I).
8. Sau khi tạo View ta khai báo các hàm trong IViewTrainingCatalog như sau
namespace CuscAppFramework.Training
{
public interface IViewTrainingCatalog
{
/// <summary>
/// Load thông tin đối tượng
/// </summary>
void LoadData();
/// <summary>
/// Thêm mới đối tượng
/// </summary>
void Add();
/// <summary>
/// Hiệu chỉnh đối tượng
/// </summary>
void Modify();
/// <summary>
/// Xóa đối tượng
/// </summary>
void Delete();
/// <summary>
/// Lưu thông tin đối tượng
/// </summary>
void Save();
/// <summary>
/// Hủy bỏ thao tác trước đó
/// </summary>
void Cancel();
}
}
Các IViewTrainingCatalogV2, IViewTrainingPlans tương tự.
Sau khi tạo View với mỗi View ta thực hiện các bước sau
Thêm sử dụng
using CuscAppFramework.Infrastructure.Interface.Services;
using Microsoft.Practices.CompositeUI;
using CuscAppFramework.Training.Interface.Constants;
Kế thùa từ ISmartPartInfoProvider
Khai báo đoạn code bắt buộc phải có của mỗi View như sau
VD: Khai báo đoạn code bắt buộc cho ViewTrainingCatalog các View còn lại tương tự chỉ
khác phần Rules
#region Phần code bắt buộc phải có của View
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
private IButtonState _buttonState;
9. /// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
[ServiceDependency]
public IButtonState ButtonState
{
get { return _buttonState; }
set { _buttonState = value; }
}
public ISmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
return _presenter.GetSmartPartInfo(smartPartInfoType);
}
void ParentForm_Activated(object sender, EventArgs e)
{
ButtonState.Init(null, Infrastructure.Interface.Enum.EnumFormStatus.VIEW,
Rules.TRAINING_CATALOG_ADD, Rules.TRAINING_CATALOG_MODIFY,
Rules.TRAINING_CATALOG_DELETE);
ButtonState.SetAllowAdd(true);
ButtonState.SetAllowDelete(true);
ButtonState.SetAllowModify(true);
}
#endregion Phần code bắt buộc phải có của View
Và nhớ thêm đoạn
//Đoạn này bắt buộc
this.ParentForm.Activated += new EventHandler(ParentForm_Activated);
vào hàm OnLoad
Cài đặt các interface đã khai báo cho View
Bằng cách Right Click vào IView tương ứng chọn Implement Interface
Nếu có tạo Test unit cho module chúng ta phải cài đạt cho Các View ở project Test Unit
Project có tên <TenModule>.<Test>
Vào View tương ứng có tên theo cấu trúc <TenView>PresenterFixture.cs tiếp theo đó cài đặt
các interface đã khai báo ở IView tương tự như cài đặt ở View.
ViewTrainingCatalog
using System;
using System.Windows.Forms;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.ObjectBuilder;
using CuscAppFramework.Infrastructure.Interface;
using CuscAppFramework.Infrastructure.Interface.Services;
using Microsoft.Practices.CompositeUI;
10. using CuscAppFramework.Training.Interface.Constants;
using System.ComponentModel;
using System.Collections;
using CuscAppFramework.Infrastructure.Interface.Enum;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingCatalog : UserControl, IViewTrainingCatalog, ISmartPartIn
foProvider
{
#region Phần code bắt buộc phải có của View
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
private IButtonState _buttonState;
private EnumFormStatus _formStatus = EnumFormStatus.VIEW;
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
[ServiceDependency]
public IButtonState ButtonState
{
get { return _buttonState; }
set { _buttonState = value; }
}
public ISmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
return _presenter.GetSmartPartInfo(smartPartInfoType);
}
void ParentForm_Activated(object sender, EventArgs e)
{
ButtonState.Init(null, Infrastructure.Interface.Enum.EnumFormStatus.
VIEW, Rules.TRAINING_CATALOG_ADD, Rules.TRAINING_CATALOG_MODIFY, Rules.TRAINING_CA
TALOG_DELETE);
ButtonState.SetAllowAdd(true);
ButtonState.SetAllowDelete(true);
ButtonState.SetAllowModify(true);
}
#endregion Phần code bắt buộc phải có của View
public ViewTrainingCatalog()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
11. base.OnLoad(e);
//Đoạn này bắt buộc
this.ParentForm.Activated += new EventHandler(ParentForm_Activated);
}
#region IViewTrainingCatalog Members
public void LoadData()
{
throw new NotImplementedException();
}
public void Add()
{
throw new NotImplementedException();
}
public void Modify()
{
throw new NotImplementedException();
}
public void Delete()
{
throw new NotImplementedException();
}
public void Save()
{
throw new NotImplementedException();
}
public void Cancel()
{
throw new NotImplementedException();
}
#endregion
}
}
Sau khi khai báo các thành phần bắt buộc phải có của View. Tiếp đến chúng ta khai báo code
cho Presenter
Code cho Presenter
Khai báo sử dụng
using CABDevExpress.SmartPartInfos;
12. Khai báo đoạn code bắt buộc phải có trên Presenter
#region Phần code bắt buộc phải có của Presenter
/// <summary>
/// XtraWindowSmartPartInfo
/// </summary>
/// <param name="smartPartInfoType"></param>
/// <returns></returns>
public XtraWindowSmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
XtraWindowSmartPartInfo smartPartInfo = (XtraWindowSmartPartInfo)Activator.CreateI
nstance(smartPartInfoType);
smartPartInfo.Title = "Danh mục đào tạo (lưới)";
return smartPartInfo;
}
#endregion Phần code bắt buộc phải có của Presenter
Các Presenter còn lại khai báo tương tự
ViewTrainingCatalogPresenter
using System;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.Practices.CompositeUI;
using CuscAppFramework.Infrastructure.Interface;
using CABDevExpress.SmartPartInfos;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingCatalogPresenter : Presenter<IViewTrainingCatalog>
{
#region Phần code bắt buộc phải có của Presenter
/// <summary>
/// XtraWindowSmartPartInfo
/// </summary>
/// <param name="smartPartInfoType"></param>
/// <returns></returns>
public XtraWindowSmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
XtraWindowSmartPartInfo smartPartInfo = (XtraWindowSmartPartInfo)Activator.CreateI
nstance(smartPartInfoType);
smartPartInfo.Title = "Danh mục đào tạo (lưới)";
return smartPartInfo;
}
#endregion Phần code bắt buộc phải có của Presenter
/// <summary>
/// This method is a placeholder that will be called by the view when it has been load
ed.
/// </summary>
public override void OnViewReady()
{
13. base.OnViewReady();
}
/// <summary>
/// Close the view
/// </summary>
public override void OnCloseView()
{
base.CloseView();
}
}
}
Sau khi tạo View, IView, Presenter và khai báo các đoạn code bắt buộc
Tiếp theo chúng ta sẽ khai báo xử lý sự kiện khi nhấn vào nút để mở chức năng (View) trên
Shell Form
Vào Module Controller
Tìm đến //TODO: Add CommandHandlers and/or Event Subscriptions
và khai báo xử lý lắng nghe các command theo hướng dẫn
// Khai báo lắng nghe sựu kiện nhấn nút Danh mục đào tạo dạng lưới
[CommandHandler(CommandNames.TRAINING_CATALOG)]
public void OnTrainingCatalogClick(object sender, EventArgs e)
{
ShowViewInWorkspace<ViewTrainingCatalog>(CuscAppFramework.Training.Interface.Const
ants.SmartPartInfoNames.TRAINING_CATALOG, WorkspaceNames.MainWorkspace);
}
// Khai báo lắng nghe sựu kiện nhấn nút Danh mục đào tạo dạng ô nhập liệu
[CommandHandler(CommandNames.TRAINING_CATALOG_V2)]
public void OnTrainingCatalogV2Click(object sender, EventArgs e)
{
ShowViewInWorkspace<ViewTrainingCatalogV2>(CuscAppFramework.Training.Interface.Con
stants.SmartPartInfoNames.TRAINING_CATALOG_V2, WorkspaceNames.MainWorkspace);
}
// Khai báo lắng nghe sựu kiện nhấn nút Kế hoạch đào tạo
[CommandHandler(CommandNames.TRAINING_PLANS)]
public void OnTrainingPlansClick(object sender, EventArgs e)
{
ShowViewInWorkspace<ViewTrainingCatalogV2>(CuscAppFramework.Training.Interface.Con
stants.SmartPartInfoNames.TRAINING_PLANS, WorkspaceNames.MainWorkspace);
}
Đến đây bạn có thể mở View từ sự kiện Click của các nút chức năng tương ứng
14. Tạo Model
Trước hết để tạo mô hình EDM chúng ta thiết kế database cho các chức năng vừa tạo gồm
ba bảng (Chỉ demo trong thực tế các bảng này không đủ thông tin để quản lý ở đây các
trường dữ liệu được cho hơi rộng so với thực tế, trong thực tế tùy lượng dữ liệu chúng ta
cho phù hợp hơn) có cấu trúc như sau:
Lưu ý: Cách đặt tên bảng và các Field trong bảng theo cấu trúc tên Function, Các trường
Id phải tự tăng
Sau khi có cấu trúc cơ sở dữ liệu tiếp theo chúng ta sẽ ánh xạ cấu trúc database lên mô
hình.
Vào Project <TenModule> Tạo thư mục tên “Model” (Tên không đổi đối với từng Module)
Right Click lên thư mục Model chọn Add -> New Item. Các bước tiếp theo hình minh họa.
Lưu ý đặt tên Model theo cấu trúc <TenModule>Model
17. Thông tin từ database được load lên mô hình như sau
18. Sau khi tạo xong Model lưu ý copy đoạn
<add name="TrainingEntities" connectionString="metadata=res://*/Model.TrainingModel.csdl|
res://*/Model.TrainingModel.ssdl|
res://*/Model.TrainingModel.msl;provider=System.Data.SqlClient;provider connection string=&quo
t;Data Source=SERVERPROJECTSMSSQL2005;Initial Catalog=qly_vat_tu;Persist Security Info=True;U
ser ID=hrmuser;Password=stapimex;MultipleActiveResultSets=True"" providerName="System.Dat
a.EntityClient" />
trong file App.config của Module đang tạo Model vào trong file App.config của Shell Project
vị trí như sau:
<connectionStrings>
<add name="qly_vat_tuEntities" connectionString="metadata=res://*/Model1.csdl|
res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection stri
ng="Data Source=SERVERPROJECTSMSSQL2005;Initial Catalog=qly_vat_tu;Persist Security Info
=True;User ID=hrmuser;Password=stapimex;MultipleActiveResultSets=True"" providerName="Sys
tem.Data.EntityClient" />
<add name="TrainingEntities" connectionStrin
g="metadata=res://*/Model.TrainingModel.csdl|
res://*/Model.TrainingModel.ssdl|
res://*/Model.TrainingModel.msl;provider=System.Data.SqlClient;provider conne
ction string="Data Source=SERVERPROJECTSMSSQL2005;Initial Catalog=qly_v
at_tu;Persist Security Info=True;User ID=hrmuser;Password=stapimex;MultipleAc
tiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
Code chức năng Danh mục đào tạo (Training) dạng lưới
Thiết kế ViewTraingCatalog
Do đây là danh mục dạng lưới vì vậy control chính sử dụng cho View này là GirdControl
Đầu tiên từ Tool box tại Tab DX.11.2: Data chọn GirdControl và kéo vào View
Các tùy chọn cho GirdControl
Click chuột vào dấu ở gốc trên bên phải (hoặc vào Properties) và chọn Dock in Parent
Đặt tên lại cho GirdControl là gcTrainingCatalog
Đặt tên lại cho GirdView là gvTrainingCatalog
Chọn vào gcTrainingCatalog tại của sổ Properties chọn UseEmbeddedNavigator =true để
sử dụng thanh navigator của gir
Chọn vào gvTrainingCatalog tại của sổ Properties chọn các thông tin hiển thị tại vị trí thêm
một dòng mới
19. Chọn vào gvTrainingCatalog tại của sổ Properties -> chọn các thông tin cho
phép hiển thị dòng tự động lọc dữ liệu, và không hiển thị group Panel (vì không cần thiết)
như sau:
Chọn vào gvTrainingCatalog tại của sổ Properties -> định dạng hiển thị số
dòng trên lưới của thanh navigator như sau:
Tiếp theo ta sẽ đặt tên và định dạng cho các cột dữ liệu cần hiển thị trên gird
Chọn vào gcTrainingCatalog-> Chọn Run Designer-> Chọn Columns
Bảng dữ liệu TrainingCatalog gồm 4 trường vì vậy cần thêm vào 4 column bằng cách click
vào nút
Cách đặt tên cho các cột Theo tên trường trong database để dễ quản lý
Ví dụ các thông tin cho trường TrainingId như sau
Thuộc tính Giá trị Ghi chú
Caption TrainingId Do không hiển thị nên đạt giống với
tên trong database
FieldName TrainingId Phải giống với tên cột trong database
Visible False Không hiển thị
Name TrainingId Phải giống với tên cột trong database
Ví dụ các thông tin cho trường TrainingCode như sau
Thuộc tính Giá trị Ghi chú
Caption Mã đào tạo
FieldName TrainingCode Phải giống với tên cột trong database
Name TrainingCode Phải giống với tên cột trong database
Ví dụ các thông tin cho trường TrainingName như sau
20. Thuộc tính Giá trị Ghi chú
Caption Tên đào tạo
FieldName TrainingName Phải giống với tên cột trong database
Name TrainingName Phải giống với tên cột trong database
Ví dụ các thông tin cho trường TrainingDescription như sau
Thuộc tính Giá trị Ghi chú
Caption Mô tả đào tạo
FieldName TrainingDescription Phải giống với tên cột trong database
Name TrainingDescription Phải giống với tên cột trong database
Sau khi Design ta có giao diện view như sau
Code cho ViewTrainingCatalogPresenter (File ViewTrainingCatalogPresenter.cs)
21. Đầu tiên ta khai báo sử dụng Model và Linq (File ViewTrainingCatalogPresenter.cs)
using Microsoft.Practices.CompositeUI.Commands;
using CuscAppFramework.Training.Interface.Constants;
using CuscAppFramework.Training.Model;
using System.Linq;
using System.Collections.Generic;
Tiếp theo (File ViewTrainingCatalogPresenter.cs)
//Khai báo biến context để lấy dữ liệu từ mô hình TrainingModel
TrainingEntities context = new TrainingEntities();
Khai báo hàm lấy dữ liệu ở Presenter
/// <summary>
///
/// Hàm trả về IQueryable<TrainingCatalog>
/// </summary>
/// <returns></returns>
public IQueryable<TrainingCatalog> GetTrainingCatalogData()
{
context = new TrainingEntities();
return context.TrainingCatalogs;
}
Tiếp theo khai báo thực thi các Command đã khai báo (File ViewTrainingCatalogPresenter.cs)
/// <summary>
/// Thực hiện lưu dữ liệu cho các thao tác thêm, sủa, xóa
/// </summary>
/// <returns></returns>
public object [] Save()
{
string strError="Lưu dữ liệu thành công.";
int result = 0;
try
{
result = context.SaveChanges();
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
/// <summary>
22. /// Thực hiện thêm thông tin trên danh mục đào tạo dạng lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.ADD)]
public void OnAdd(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalog)
{
View.Add();
}
}
/// <summary>
/// Thực hiện sửa thông tin trên danh mục đào tạo dạng lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.MODIFY)]
public void OnModify(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalog)
{
View.Modify();
}
}
/// <summary>
/// Thực hiện xóa thông tin trên danh mục đào tạo dạng lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.DELETE)]
public void OnDelete(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalog)
{
View.Delete();
}
}
/// <summary>
/// Thực hiện lưu thông tin trên danh mục đào tạo dạng lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.SAVE)]
public void OnSave(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalog)
{
View.Save();
}
}
/// <summary>
23. /// Thực hiện bỏ qua trên danh mục đào tạo dạng lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.CANCEL)]
public void OnCancel(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalog)
{
View.Cancel();
}
}
Sau khi khai báo các hàm xử lý sự kiện ở Presenter , tiếp theo chúng ta code tiếp cho View
File ViewTrainingCatalog.cs
Khai báo sử dụng Model
using CuscAppFramework.Training.Model;
/// <summary>
/// Trạng thái trên Form
/// Khi form có nhiều control chúng ta sẽ điều khiển các control trong hàm này
/// </summary>
[Category("ViewTrainingCatalog")]
public EnumFormStatus FormStatus
{
get { return _formStatus; }
set
{
_formStatus = value;
if (_formStatus == EnumFormStatus.ADD)
{
gvTrainingCatalog.OptionsBehavior.Editable = true;
}
else if (_formStatus == EnumFormStatus.MODIFY)
{
gvTrainingCatalog.OptionsBehavior.Editable = true;
}
else
{
gvTrainingCatalog.OptionsBehavior.Editable = false;
}
}
}
public ViewTrainingCatalog()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
base.OnLoad(e);
LoadData();
this.ParentForm.Activated += new EventHandler(ParentForm_Activated);
24. }
#region IViewTrainingCatalog Members
/// <summary>
/// Load dữ liệu lên gird
/// </summary>
public void LoadData()
{
gcTrainingCatalog.DataSource= _presenter.GetTrainingCatalogData();
gvTrainingCatalog.OptionsView.NewItemRowPosition = DevExpress.XtraGrid.Views.Grid.
NewItemRowPosition.None;
this.FormStatus = EnumFormStatus.VIEW;
}
/// <summary>
/// Thực hiện thêm
/// </summary>
public void Add()
{
ButtonState.AddMode();
this.FormStatus = EnumFormStatus.ADD;
gvTrainingCatalog.OptionsView.NewItemRowPosition = DevExpress.XtraGrid.Views.Grid.
NewItemRowPosition.Top;
}
/// <summary>
/// Thực hiện sủa
/// </summary>
public void Modify()
{
ButtonState.ModifyMode();
this.FormStatus = EnumFormStatus.MODIFY;
}
/// <summary>
/// Thực hiện xóa
/// </summary>
public void Delete()
{
try
{
if (gvTrainingCatalog.SelectedRowsCount > 0 )
{
if (XtraMessageBox.Show(this.ParentForm, "Bạn có chắc muốn xóa thông tin đ
ào tạo này không ?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxD
efaultButton.Button2) == DialogResult.Yes)
{
gvTrainingCatalog.DeleteSelectedRows();
gvTrainingCatalog.UpdateCurrentRow();
object[] result = _presenter.Save();
if (!Convert.ToBoolean(result[0]))
{
25. XtraMessageBox.Show("Lỗi khi xóa thông tin đào tạo." + result[1],
"Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
else
{
XtraMessageBox.Show("Bạn chưa chọn thông tin đào tạo cần xóa.", "Thông báo
", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch
{
XtraMessageBox.Show("Lỗi khi xóa thông tin đào tạo.", "Lỗi", MessageBoxButtons
.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Lưu thông tin đào tạo
/// </summary>
public void Save()
{
gvTrainingCatalog.PostEditor();
gvTrainingCatalog.UpdateCurrentRow();
gvTrainingCatalog.CloseEditor();
object [] result =_presenter.Save();
if (Convert.ToBoolean(result[0]))
{
LoadData();
ButtonState.SaveMode();
}
else
{
XtraMessageBox.Show("Lỗi khi lưu thông tin đào tạo." + result[1].ToString(), "
Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Thực hiện bỏ qua
/// </summary>
public void Cancel()
{
ButtonState.CancelMode();
this.FormStatus = EnumFormStatus.VIEW;
}
Đến đây view đã có được các xử lý cơ bản( Thêm, sửa, xóa)
Tiếp theo chúng ta sẽ tìm hiểu cách kiểm tra một số lỗi đơn giản trên lưới
Ví dụ thông tin mã đào tạo và tên đào tạo không được phép rỗng nên ta sẽ thực hiện kiểm
tra tại client
26. Đầu tiên ta kiểm tra lỗi trên dòng. Vì lỗi trên dòng sẽ hiển thị dạng MessageBox rất bất
tiện->
Chúng ta sẽ không cho hiển thị thông báo lỗi dạng này bằng cách chọn gvTrainingCatalog
-> Properties -> Chọn sự kiện ->InvalidRowException và khai báo đoạn code sau trong sự
kiện này
/// <summary>
/// Không hiển thị lỗi dạng MessageBox
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void gvTrainingCatalog_InvalidRowException(object sender, DevExpress.XtraGrid.
Views.Base.InvalidRowExceptionEventArgs e)
{
e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
}
Tiếp theo ta sẽ kiểm tra theo sự kiện ValidatingEditor
Chọn gvTrainingCatalog -> Properties -> Chọn sự kiện -> ValidatingEditor
Khai báo đoạn code sau
/// <summary>
/// Kiểm tra dữ liệu tại ô nhập liệu tương ứng
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void gvTrainingCatalog_ValidatingEditor(object sender, DevExpress.XtraEditors.
Controls.BaseContainerValidateEditorEventArgs e)
{
if (gvTrainingCatalog.FocusedRowHandle == GridControl.AutoFilterRowHandle)
{
return;
}
if (gvTrainingCatalog.FocusedColumn.FieldName == "TrainingCode" || gvTrainingCatal
og.FocusedColumn.FieldName == "TrainingName")
{
if (string.IsNullOrEmpty((string)e.Value))
{
e.ErrorText =gvTrainingCatalog.FocusedColumn.Caption + " không thể rỗng.";
e.Valid = false;
}
}
}
Tiếp theo ta sẽ kiểm tra theo sự kiện ValidateRow
Chọn gvTrainingCatalog -> Properties -> Chọn sự kiện -> ValidateRow
27. Khai báo đoạn code sau
private void gvTrainingCatalog_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.Vali
dateRowEventArgs e)
{
TrainingCatalog training;
try
{
training = e.Row as TrainingCatalog;
if (training == null)
{
return;
}
if (string.IsNullOrEmpty(training.TrainingCode))
{
gvTrainingCatalog.SetColumnError(gvTrainingCatalog.Columns["TrainingCode"]
, "Mã đào tạo không thể rỗng và không được phép trùng.", DevExpress.XtraEditors.DXErrorProvide
r.ErrorType.Default);
e.Valid = false;
}
else if (string.IsNullOrEmpty(training.TrainingName))
{
gvTrainingCatalog.SetColumnError(gvTrainingCatalog.Columns["TrainingName"]
, "Tên đào tạo không thể rỗng.", DevExpress.XtraEditors.DXErrorProvider.ErrorType.Default);
e.Valid = false;
}
else
{
gvTrainingCatalog.ClearColumnErrors();
}
}
finally
{
training = null;
}
}
Các đoạn code sau chỉ minh họa cho việc kiểm tra lỗi trên lưới trên thực tế sẽ phải kiểm tra
nhiều hơn về miền giá trị hợp lệ của dữ liệu, dữ liệu được sử dụng bởi chức năng khác…,
dữ liệu trùng…
Về cơ bản tại client nếu dạng lưới có 2 cách kiểm tra như trên
Đồng thời bạn phải kiểm tra lỗi tại server để đưa ra thông báo lỗi chính xác bằng tiếng Việt
Ở đây trong khuôn khổ hướng dẫn này chưa thực hiện
Code chức năng Danh mục đào tạo dạng ô nhập liệu
Giao diện chức năng như sau:
Phần lưới dữ liệu giống chức năng Danh mục đào tạo dạng lưới
Chỉ khác do không nhập dữ liệu trực tiếp trên lưới nên ta sẽ đặt thuộc tính Editable = False
28. Các ô nhập liệu(Nên đặt giống với tên database cho dễ quản lý theo cấu trúc
<controlType><FieldName>):
Mã đào tạo: txtTrainingCode
Tên đào tạo: txtTrainingName
Mô tả: txtTrainingDescription
Lưu ý đặt Maxlength và TabIndex cho các ô nhập liệu cho đúng
Thông tin TraingId cũng được thiết kế là một Text box tên là txtTraingId, do thông tin này
không hiển thị với người dùng nên chọn Send to Back một control khác (Vì đặt visible =
False không binding được)
Có thể thắc mắc thông tin không hiển thị tại sao thiết kế là một TextBox mà không phải là
một biến
Lý do đơn giản là vì chúng ta cần binding dữ liệu từ gird lên các ô nhập liệu vì vậy thiết kế
là text control cho dễ (Bạn có thể cho thông tin này vào biến vẫn được)
Lưu ý: Các control được nhập liệu đạt lại thuộc tính Anchor = Top (Mặc định là Top, Left)
Để khi thay đổi kích thước form các control được canh vào giữa và không bị chạy qua trái
29. Đến đây sẽ không đi vào chi tiết từng phần nữa mà chỉ đưa ra đoạn code để tham khảo
Phần bắt lỗi vào giao diện các bạn tự kiểm tra và thiết kế lại
Code ViewTrainingCatalogV2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using CuscAppFramework.Infrastructure.Interface;
using CuscAppFramework.Infrastructure.Interface.Enum;
using CuscAppFramework.Infrastructure.Interface.Services;
using CuscAppFramework.Training.Interface.Constants;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.ObjectBuilder;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingCatalogV2 : UserControl, IViewTrainingCatalogV2,ISmartPar
tInfoProvider
{
#region Phần code bắt buộc phải có của View
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
private IButtonState _buttonState;
private EnumFormStatus _formStatus = EnumFormStatus.VIEW;
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
[ServiceDependency]
public IButtonState ButtonState
{
get { return _buttonState; }
set { _buttonState = value; }
}
public ISmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
return _presenter.GetSmartPartInfo(smartPartInfoType);
}
void ParentForm_Activated(object sender, EventArgs e)
{
ButtonState.Init(gvTrainingCatalogV2, Infrastructure.Interface.Enum.EnumFormStatus
.
30. VIEW, Rules.TRAINING_CATALOG_V2_ADD, Rules.TRAINING_CATALOG_V2_MODIFY, Rules.TRAIN
ING_CATALOG_V2_DELETE);
ButtonState.SetAllowAdd(true);
ButtonState.SetAllowDelete(true);
ButtonState.SetAllowModify(true);
}
#endregion Phần code bắt buộc phải có của View
public ViewTrainingCatalogV2()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
base.OnLoad(e);
LoadData();
this.ParentForm.Activated += new EventHandler(ParentForm_Activated);
}
#region IViewTrainingCatalogV2 Members
/// <summary>
/// Clear data binding
/// </summary>
void ClearData()
{
txtTrainingId.DataBindings.Clear();
txtTrainingCode.DataBindings.Clear();
txtTrainingName.DataBindings.Clear();
txtTrainingDescription.DataBindings.Clear();
txtTrainingId.Text = "";
txtTrainingCode.Text = "";
txtTrainingName.Text = "";
txtTrainingDescription.Text = "";
}
/// <summary>
/// Binding Data
/// </summary>
void BindingData()
{
ClearData();
txtTrainingId.DataBindings.Add("EditValue", gcTrainingCatalogV2.DataSource, Traini
ngId.FieldName);
txtTrainingCode.DataBindings.Add("EditValue", gcTrainingCatalogV2.DataSource, Trai
ningCode.FieldName);
txtTrainingName.DataBindings.Add("EditValue", gcTrainingCatalogV2.DataSource, Trai
ningName.FieldName);
txtTrainingDescription.DataBindings.Add("EditValue", gcTrainingCatalogV2.DataSourc
e, TrainingDescription.FieldName);
}
31. /// <summary>
/// Trạng thái trên Form
/// Khi form có nhiều control chúng ta sẽ điều khiển các control trong hàm này
/// </summary>
[Category("ViewTrainingCatalogV2")]
public EnumFormStatus FormStatus
{
get { return _formStatus; }
set
{
_formStatus = value;
if (_formStatus == EnumFormStatus.ADD || _formStatus == EnumFormStatus.MODIFY)
{
txtTrainingId.Properties.ReadOnly = false;
txtTrainingCode.Properties.ReadOnly = false;
txtTrainingName.Properties.ReadOnly = false;
txtTrainingDescription.Properties.ReadOnly = false;
gcTrainingCatalogV2.Enabled = false;
if (_formStatus == EnumFormStatus.ADD)
{
ClearData();
}
}
else
{
txtTrainingId.Properties.ReadOnly = true;
txtTrainingCode.Properties.ReadOnly = true;
txtTrainingName.Properties.ReadOnly = true;
txtTrainingDescription.Properties.ReadOnly = true;
gcTrainingCatalogV2.Enabled = true;
}
}
}
/// <summary>
/// Load dữ liệu
/// </summary>
public void LoadData()
{
gcTrainingCatalogV2.DataSource = _presenter.GetTrainingCatalogData();
BindingData();
FormStatus = EnumFormStatus.VIEW;
}
/// <summary>
/// Thêm dữ liệu
/// </summary>
public void Add()
{
ButtonState.AddMode();
this.FormStatus = EnumFormStatus.ADD;
}
/// <summary>
/// Sủa dữ liệu
/// </summary>
public void Modify()
{
ButtonState.ModifyMode();
this.FormStatus = EnumFormStatus.MODIFY;
32. }
/// <summary>
/// Xóa dữ liệu
/// </summary>
public void Delete()
{
try
{
if (gvTrainingCatalogV2.SelectedRowsCount > 0 && gvTrainingCatalogV2.FocusedRo
wHandle != GridControl.AutoFilterRowHandle)
{
if (XtraMessageBox.Show(this.ParentForm, "Bạn có chắc muốn xóa thông tin đ
ào tạo này không ?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxD
efaultButton.Button2) == DialogResult.Yes)
{
object[] result;
result = _presenter.DeleteTraining(Convert.ToInt64(gvTrainingCatalogV2
.GetFocusedRowCellValue(TrainingId.FieldName)));
if (Convert.ToBoolean(result[0]))
{
LoadData();
}
else
{
XtraMessageBox.Show("Lỗi khi xóa thông tin đào tạo." + result[1].T
oString(), "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
else
{
XtraMessageBox.Show("Bạn chưa chọn thông tin đào tạo cần xóa.", "Thông báo
", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch
{
XtraMessageBox.Show("Lỗi khi xóa thông tin đào tạo.", "Lỗi", MessageBoxButtons
.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Kiểm tra dữ liệu hợp lệ
/// </summary>
/// <returns></returns>
bool ValidateData()
{
string strError="";
if (string.IsNullOrEmpty(txtTrainingCode.Text))
{
strError += "Mã đào tạo không được rỗng.";
}
if (string.IsNullOrEmpty(txtTrainingName.Text))
{
strError += (strError == "" ? "Tên đào tạo không được rỗng." : "nTên đào tạo
không được rỗng.");
}
33. if (strError != "")
{
XtraMessageBox.Show(strError, "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Erro
r);
return false;
}
return true;
}
/// <summary>
/// Lưu dữ liệu thêm và sửa
/// </summary>
public void Save()
{
if (!ValidateData())
{
return;
}
object[] result;
Int64 trainingId = Convert.ToInt64(string.IsNullOrEmpty(txtTrainingId.Text) ? "0"
: txtTrainingId.Text);
string trainingCode = txtTrainingCode.Text.Trim();
string trainingName = txtTrainingName.Text.Trim();
string trainingDescription = txtTrainingDescription.Text.Trim();
if (FormStatus == EnumFormStatus.ADD)
{
result = _presenter.AddNewTraining(trainingCode, trainingName, trainingDescrip
tion);
}
else
{
result = _presenter.ModifyTraining(trainingId,trainingCode, trainingName, trai
ningDescription);
}
if (Convert.ToBoolean(result[0]))
{
LoadData();
ButtonState.SaveMode();
}
else
{
XtraMessageBox.Show("Lỗi khi lưu thông tin đào tạo." + result[1].ToString(), "
Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void Cancel()
{
ButtonState.CancelMode();
BindingData();
this.FormStatus = EnumFormStatus.VIEW;
}
#endregion
}
}
34. Code ViewtraingCatalogV2Presenter
using System;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.Practices.CompositeUI;
using CuscAppFramework.Infrastructure.Interface;
using CABDevExpress.SmartPartInfos;
using Microsoft.Practices.CompositeUI.Commands;
using CuscAppFramework.Training.Interface.Constants;
using CuscAppFramework.Training.Model;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingCatalogV2Presenter : Presenter<IViewTrainingCatalogV2>
{
TrainingEntities context = new TrainingEntities();
#region Phần code bắt buộc phải có của Presenter
/// <summary>
/// XtraWindowSmartPartInfo
/// </summary>
/// <param name="smartPartInfoType"></param>
/// <returns></returns>
public XtraWindowSmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
XtraWindowSmartPartInfo smartPartInfo = (XtraWindowSmartPartInfo)Activator.CreateI
nstance(smartPartInfoType);
smartPartInfo.Title = "Danh mục đào tạo (ô nhập liệu)";
return smartPartInfo;
}
#endregion Phần code bắt buộc phải có của Presenter
/// <summary>
///
/// Hàm trả về IQueryable<TrainingCatalog>
/// </summary>
/// <returns></returns>
public IQueryable<TrainingCatalog> GetTrainingCatalogData()
{
context = new TrainingEntities();
return context.TrainingCatalogs;
}
#region Phần code xử lý thêm, sủa, xóa
/// <summary>
/// Thực hiện thêm mới trên danh mục đào tạo
/// </summary>
/// <returns></returns>
public object[] AddNewTraining(string trainingCode, string trainingName, string traini
ngDescription)
{
string strError = "Lưu dữ liệu thành công.";
35. int result = 0;
try
{
using (var contexts = new TrainingEntities())
{
TrainingCatalog training = new TrainingCatalog();
training.TrainingCode = trainingCode.Trim();
training.TrainingName = trainingName.Trim();
training.TrainingDescription = trainingDescription.Trim();
contexts.TrainingCatalogs.AddObject(training);
result = contexts.SaveChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
/// <summary>
/// Thực hiện sửa trên danh mục đào tạo
/// </summary>
/// <returns></returns>
public object[] ModifyTraining(Int64 trainingId, string trainingCode, string trainingN
ame, string trainingDescription)
{
string strError = "Lưu dữ liệu thành công.";
int result = 0;
try
{
using (var contexts = new TrainingEntities())
{
var training = contexts.TrainingCatalogs.First(p => p.TrainingId == traini
ngId);
training.TrainingCode = trainingCode.Trim();
training.TrainingName = trainingName.Trim();
training.TrainingDescription = trainingDescription.Trim();
result = contexts.SaveChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
/// <summary>
/// Thực hiện xóa trên danh mục đào tạo
/// </summary>
/// <returns></returns>
public object[] DeleteTraining(Int64 trainingId)
{
36. string strError = "Xóa dữ liệu thành công.";
int result = 0;
try
{
using (var contexts = new TrainingEntities())
{
var training = contexts.TrainingCatalogs.First(p => p.TrainingId == traini
ngId);
contexts.TrainingCatalogs.DeleteObject(training);
result= contexts.SaveChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
#endregion Phần code xử lý cthêm, sủa, xóa
#region Phần code xử lý các sự kiện thêm, sủa, xóa
/// <summary>
/// Thực hiện thêm thông tin trên danh mục đào tạo dạng ô nhập liệu
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.ADD)]
public void OnAdd(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalogV2)
{
View.Add();
}
}
/// <summary>
/// Thực hiện sửa thông tin trên danh mục đào tạo dạng ô nhập liệu
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.MODIFY)]
public void OnModify(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalogV2)
{
View.Modify();
}
}
/// <summary>
/// Thực hiện xóa thông tin trên danh mục đào tạo dạng ô nhập liệu
/// </summary>
/// <param name="sender"></param>
37. /// <param name="e"></param>
[CommandHandler(CommandNames.DELETE)]
public void OnDelete(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalogV2)
{
View.Delete();
}
}
/// <summary>
/// Thực hiện lưu thông tin trên danh mục đào tạo dạng ô nhập liệu
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.SAVE)]
public void OnSave(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalogV2)
{
View.Save();
}
}
/// <summary>
/// Thực hiện bỏ qua trên danh mục đào tạo dạng ô nhập liệu
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.CANCEL)]
public void OnCancel(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingCatalogV2)
{
View.Cancel();
}
}
#endregion Phần code xử lý các sự kiện thêm, sủa, xóa
/// <summary>
/// This method is a placeholder that will be called by the view when it has been load
ed.
/// </summary>
public override void OnViewReady()
{
base.OnViewReady();
}
/// <summary>
/// Close the view
/// </summary>
public override void OnCloseView()
{
38. base.CloseView();
}
}
}
Code chức năng Kế hoạch đào tạo
Giao diện chức năng cớ bản như sau
Các chức năng trước đã giới thiệu cách tạo giao diện
Phần này sẽ không giới thiệu lại
Do Entity của TrainingPlan không có cột chọn nhưng lưới hiển thị có cột chọn để in các kế
hoạch được chọn nên ta sẽ thực hiện viết Model cho View này
Khi đó chúng ta vào thư mục Model của Module tạo một lớp (Class) mới tên
Model này chỉ mang tính chất giới thiệu cách tạo Model
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using CuscAppFramework.Training.Model;
namespace CuscAppFramework.Training.Model
39. {
public class TrainingPlanModel
{
public System.Int64 TrainingPlanId
{ get; set; }
public System.String TrainingPlanCode
{ get; set; }
public System.DateTime TrainingPlanDate
{ get; set; }
public System.String TrainingPlanDescription
{ get; set; }
public System.Boolean Select
{ get; set; }
/// <summary>
/// Trả về danh sách các kế hoạch đào tạo
/// </summary>
/// <param name="tuNgay"></param>
/// <param name="denNgay"></param>
/// <returns></returns>
public static List<TrainingPlanModel> TrainingPlanList(DateTime tuNgay, DateTime denNga
y)
{
tuNgay = new DateTime(tuNgay.Year, tuNgay.Month, tuNgay.Day, 0, 0, 0);
denNgay = new DateTime(denNgay.Year, denNgay.Month, denNgay.Day, 23, 59, 59);
using (var contexts = new TrainingEntities())
{
return (from p in contexts.TrainingPlans
where p.TrainingPlanDate >= tuNgay
&& p.TrainingPlanDate <= denNgay
select new TrainingPlanModel {
TrainingPlanId=p.TrainingPlanId,
TrainingPlanCode=p.TrainingPlanCode,
TrainingPlanDate=p.TrainingPlanDate,
TrainingPlanDescription=p.TrainingPlanDescription,
Select=false
}
).OrderBy(p => p.TrainingPlanDate).ThenBy(p => p.TrainingPlanCode).ToL
ist<TrainingPlanModel>();
}
}
}
}
Code cho ViewTrainingPlan
Cách kiểm lỗi đã được hướng dẫn ở chức năng khác nên chức năng này không thực hiện lại
việc kiểm tra lỗi
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using CuscAppFramework.Infrastructure.Interface;
40. using CuscAppFramework.Infrastructure.Interface.Enum;
using CuscAppFramework.Infrastructure.Interface.Services;
using CuscAppFramework.Training.Interface.Constants;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using Microsoft.Practices.CompositeUI;
using Microsoft.Practices.CompositeUI.SmartParts;
using Microsoft.Practices.ObjectBuilder;
using CuscAppFramework.Training.Model;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingPlans : UserControl, IViewTrainingPlans, ISmartPartInfoPr
ovider
{
#region Phần code bắt buộc phải có của View
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
private IButtonState _buttonState;
/// <summary>
/// Trạng thái của form
/// </summary>
private EnumFormStatus _formStatus = EnumFormStatus.VIEW;
/// <summary>
/// Load lần đầu tiên
/// </summary>
private bool firstLoad = true;
/// <summary>
/// Trạng thái các nút thêm, sửa, xóa, lưu và bỏ qua trên QuickAccess
/// </summary>
[ServiceDependency]
public IButtonState ButtonState
{
get { return _buttonState; }
set { _buttonState = value; }
}
public ISmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
return _presenter.GetSmartPartInfo(smartPartInfoType);
}
void ParentForm_Activated(object sender, EventArgs e)
{
ButtonState.Init(gvTrainingPlan, Infrastructure.Interface.Enum.EnumFormStatus.
VIEW, Rules.TRAINING_PLANS_ADD, Rules.TRAINING_PLANS_MODIFY, Rules.TRAINING_PLANS_
DELETE);
ButtonState.SetAllowAdd(true);
ButtonState.SetAllowDelete(true);
ButtonState.SetAllowModify(true);
}
#endregion Phần code bắt buộc phải có của View
public ViewTrainingPlans()
{
41. InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
_presenter.OnViewReady();
base.OnLoad(e);
this.ParentForm.Activated += new EventHandler(ParentForm_Activated);
deFromDate.DateTime = DateTime.Now;
deToDate.DateTime = DateTime.Now;
LoadData();
firstLoad = false;
}
#region IViewTrainingPlans Members
/// <summary>
/// Xóa dữ liệu binding
/// </summary>
void ClearData()
{
txtTrainingPlanId.DataBindings.Clear();
txtTrainingPlanCode.DataBindings.Clear();
deTrainingPlanDate.DataBindings.Clear();
txtTrainingPlanDescription.DataBindings.Clear();
txtTrainingPlanId.Text = "";
txtTrainingPlanCode.Text = "";
deTrainingPlanDate.DateTime = DateTime.Now;
txtTrainingPlanDescription.Text = "";
}
/// <summary>
/// Binding Data
/// </summary>
void BindingData()
{
ClearData();
txtTrainingPlanId.DataBindings.Add("EditValue", gcTrainingPlan.DataSource, Trainin
gPlanId.FieldName);
txtTrainingPlanCode.DataBindings.Add("EditValue", gcTrainingPlan.DataSource, Train
ingPlanCode.FieldName);
deTrainingPlanDate.DataBindings.Add("EditValue", gcTrainingPlan.DataSource, Traini
ngPlanDate.FieldName);
txtTrainingPlanDescription.DataBindings.Add("EditValue", gcTrainingPlan.DataSource
, TrainingPlanDescription.FieldName);
}
/// <summary>
/// Trạng thái trên Form
/// Khi form có nhiều control chúng ta sẽ điều khiển các control trong hàm này
/// </summary>
[Category("ViewTrainingPlans")]
public EnumFormStatus FormStatus
{
get { return _formStatus; }
set
{
_formStatus = value;
if (_formStatus == EnumFormStatus.ADD || _formStatus == EnumFormStatus.MODIFY)
43. gcDetailTrainingPlan.DataSource = _presenter.GetNewDetailTrainingPlanData();
}
}
public void SetDetailTrainingPlan(BindingList<DetailTrainingPlan> detailData)
{
_presenter.SetDetailTrainingPlan(detailData);
}
/// <summary>
/// Thêm dữ liệu
/// </summary>
public void Add()
{
ButtonState.AddMode();
this.FormStatus = EnumFormStatus.ADD;
}
/// <summary>
/// Sủa dữ liệu
/// </summary>
public void Modify()
{
ButtonState.ModifyMode();
this.FormStatus = EnumFormStatus.MODIFY;
}
/// <summary>
/// Xóa dữ liệu
/// Cần kiểm tra thông tin đã được sử dụng
/// </summary>
public void Delete()
{
try
{
if (gvTrainingPlan.SelectedRowsCount > 0 && gvTrainingPlan.FocusedRowHandle !=
GridControl.AutoFilterRowHandle)
{
if (XtraMessageBox.Show(this.ParentForm, "Bạn có chắc muốn xóa kế hoạch đà
o tạo này không ?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDe
faultButton.Button2) == DialogResult.Yes)
{
object[] result;
result = _presenter.DeleteTrainingPlan(Convert.ToInt64(gvTrainingPlan.
GetFocusedRowCellValue(TrainingPlanId.FieldName)));
if (Convert.ToBoolean(result[0]))
{
LoadData();
}
else
{
XtraMessageBox.Show("Lỗi khi xóa thông tin kế hoạch đào tạo." + re
sult[1].ToString(), "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
else
{
XtraMessageBox.Show("Bạn chưa chọn thông tin kế hoạch đào tạo cần xóa.",
"Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
44. catch
{
XtraMessageBox.Show("Lỗi khi xóa thông tin đào tạo.", "Lỗi", MessageBoxButtons
.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Lưu dữ liệu
/// Cần thêm hàm kiểm tra dữ liệu
/// </summary>
public void Save()
{
object[] result;
Int64 trainingPlanId = Convert.ToInt64(string.IsNullOrEmpty(txtTrainingPlanId.Text
) ? "0" : txtTrainingPlanId.Text);
string trainingPlanCode = txtTrainingPlanCode.Text.Trim();
DateTime trainingPlanDate = deTrainingPlanDate.DateTime;
string trainingPlanDescription = txtTrainingPlanDescription.Text.Trim();
gvDetailTrainingPlan.PostEditor();
gvDetailTrainingPlan.UpdateCurrentRow();
gvDetailTrainingPlan.CloseEditor();
if (FormStatus == EnumFormStatus.ADD)
{
SetDetailTrainingPlan((BindingList<DetailTrainingPlan>)gcDetailTrainingPlan.Da
taSource);
result = _presenter.AddNewTraining(trainingPlanCode, trainingPlanDate, trainin
gPlanDescription);
}
else
{
result = _presenter.ModifyTraining(trainingPlanId, trainingPlanCode, trainingP
lanDate, trainingPlanDescription);
}
if (Convert.ToBoolean(result[0]))
{
LoadData();
ButtonState.SaveMode();
}
else
{
XtraMessageBox.Show("Lỗi khi lưu thông tin đào tạo." + result[1].ToString(), "
Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// Bỏ qua cần xủa lý thêm
/// </summary>
public void Cancel()
{
ButtonState.CancelMode();
LoadData();
}
#endregion
/// <summary>
45. /// Thay đổi từ ngày load lại danh sách kế hoạch
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void deFromDate_EditValueChanged(object sender, EventArgs e)
{
if (!firstLoad)
{
LoadData();
}
}
/// <summary>
/// Thay đổi đến ngày load lại danh sách kế hoạch
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void deToDate_EditValueChanged(object sender, EventArgs e)
{
if (!firstLoad)
{
LoadData();
}
}
/// <summary>
/// Mỗi khi chọn kế hoach đào tạo khác sẽ load lại thông tin chi tiết
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtTrainingPlanId_TextChanged(object sender, EventArgs e)
{
LoadDetailData();
}
/// <summary>
/// Xử lý sự kiện nhấn nút delete trên lưới
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void gcDetailTrainingPlan_KeyDown(object sender, KeyEventArgs e)
{
if (FormStatus == EnumFormStatus.ADD || FormStatus == EnumFormStatus.MODIFY)
{
if (e.KeyCode == Keys.Delete)
{
if (gvDetailTrainingPlan.RowCount > 1)
{
if (XtraMessageBox.Show(this.ParentForm, "Bạn có chắc muốn xóa thông t
in này không ?", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefau
ltButton.Button2) == DialogResult.Yes)
{
gvDetailTrainingPlan.DeleteSelectedRows();
}
}
else
{
XtraMessageBox.Show("Kế hoạch đào tạo phải có ít nhất 1 chi tiết", "L
ỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
46. }
}
}
}
Code cho ViewTrainingPlanPresenter
using System;
using Microsoft.Practices.ObjectBuilder;
using Microsoft.Practices.CompositeUI;
using CuscAppFramework.Infrastructure.Interface;
using CABDevExpress.SmartPartInfos;
using Microsoft.Practices.CompositeUI.Commands;
using CuscAppFramework.Training.Interface.Constants;
using CuscAppFramework.Training.Model;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
namespace CuscAppFramework.Training
{
public partial class ViewTrainingPlansPresenter : Presenter<IViewTrainingPlans>
{
//Khai báo biến context để lấy dữ liệu từ mô hình TrainingModel
TrainingEntities context = new TrainingEntities();
private BindingList<DetailTrainingPlan> detailTrainingPlan = new BindingList<DetailTr
ainingPlan>();
public void SetDetailTrainingPlan(BindingList<DetailTrainingPlan> detailData)
{
detailTrainingPlan = detailData;
}
#region Phần code bắt buộc phải có của Presenter
/// <summary>
/// XtraWindowSmartPartInfo
/// </summary>
/// <param name="smartPartInfoType"></param>
/// <returns></returns>
public XtraWindowSmartPartInfo GetSmartPartInfo(Type smartPartInfoType)
{
XtraWindowSmartPartInfo smartPartInfo = (XtraWindowSmartPartInfo)Activator.CreateI
nstance(smartPartInfoType);
smartPartInfo.Title = "Kế hoạch đào tạo";
return smartPartInfo;
}
#endregion Phần code bắt buộc phải có của Presenter
#region Phần code lấy dữ liệu và sử lý thêm, sủa, xóa
47. public List<TrainingPlanModel> GetTrainingPlanData(DateTime tuNgay, DateTime denNgay)
{
context = new TrainingEntities();
return TrainingPlanModel.TrainingPlanList(tuNgay, denNgay);
}
public IQueryable<DetailTrainingPlan> GetDetailTrainingPlanData(Int64 traingPlanId)
{
detailTrainingPlan.Clear();
var result = (from p in context.DetailTrainingPlans where p.TrainingPlanId == trai
ngPlanId select p);
//foreach (DetailTrainingPlan data in result)
//{
// detailTrainingPlan.Add(new DetailTrainingPlan
// {
// TrainingId=data.TrainingId,
// TrainingPlanId = data.TrainingPlanId,
// DetailTrainingPlanId=data.DetailTrainingPlanId,
// DetailTrainingPlanDescription=data.DetailTrainingPlanDescription,
// DetailTrainingPlanFromDate=data.DetailTrainingPlanFromDate,
// DetailTrainingPlanToDate=data.DetailTrainingPlanToDate
// });
//}
return result;
}
public BindingList<DetailTrainingPlan> GetNewDetailTrainingPlanData()
{
detailTrainingPlan = new BindingList<DetailTrainingPlan>();
return detailTrainingPlan;
}
public IQueryable<TrainingCatalog> GetTrainingCatalogData()
{
context = new TrainingEntities();
return context.TrainingCatalogs;
}
#endregion Phần code lấy dữ liệu và sử lý thêm, sủa, xóa
#region Phần code xử lý thêm, sủa, xóa
/// <summary>
/// Thực hiện thêm mới trên danh mục đào tạo
/// </summary>
/// <returns></returns>
public object[] AddNewTraining(string trainingPlanCode, DateTime trainingPlanDate, str
ing trainingPlanDescription)
{
string strError = "Lưu dữ liệu thành công.";
int result = 0;
try
{
using (var contexts = new TrainingEntities())
{
TrainingPlan trainingPlan = new TrainingPlan();
trainingPlan.TrainingPlanCode = trainingPlanCode.Trim();
48. trainingPlan.TrainingPlanDate = trainingPlanDate;
trainingPlan.TrainingPlanDescription = trainingPlanDescription.Trim();
contexts.TrainingPlans.AddObject(trainingPlan);
foreach (DetailTrainingPlan detail in detailTrainingPlan)
{
trainingPlan.DetailTrainingPlans.Add(detail);
}
result = contexts.SaveChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
/// <summary>
/// Thực hiện sửa trên danh mục đào tạo
/// </summary>
/// <returns></returns>
public object[] ModifyTraining(Int64 trainingPlanId, string trainingPlanCode, DateTime
trainingPlanDate, string trainingPlanDescription)
{
string strError = "Lưu dữ liệu thành công.";
int result = 0;
try
{
var training = context.TrainingPlans.First(p => p.TrainingPlanId == trainingPl
anId);
training.TrainingPlanCode = trainingPlanCode.Trim();
training.TrainingPlanDate = trainingPlanDate;
training.TrainingPlanDescription = trainingPlanDescription.Trim();
foreach (System.Data.Objects.ObjectStateEntry _entry in context.ObjectStateMan
ager.GetObjectStateEntries(System.Data.EntityState.Added).Where(s => s.Entity is DetailTrainin
gPlan))
{
(_entry.Entity as DetailTrainingPlan).TrainingPlanId = training.TrainingPl
anId;
}
result += context.SaveChanges();
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
/// <summary>
/// Thực hiện xóa trên danh mục đào tạo
/// </summary>
49. /// <returns></returns>
public object[] DeleteTrainingPlan(Int64 trainingPlanId)
{
string strError = "Xóa dữ liệu thành công.";
int result = 0;
try
{
using (var contexts = new TrainingEntities())
{
var detailTrainingPlans = from p in contexts.DetailTrainingPlans
where p.TrainingPlanId == trainingPlanId
select p;
foreach (var detail in detailTrainingPlans)
{
contexts.DeleteObject(detail);
}
var trainingPlans = contexts.TrainingPlans.First(p => p.TrainingPlanId ==
trainingPlanId);
contexts.TrainingPlans.DeleteObject(trainingPlans);
result = contexts.SaveChanges();
}
}
catch (Exception ex)
{
strError = ex.Message;
}
return new object[] { result > 0 ? true : false, strError };
}
#endregion Phần code xử lý cthêm, sủa, xóa
#region Phần code xử lý các sự kiện thêm, sủa, xóa
/// <summary>
/// Thực hiện thêm thông tin trên kế hoạch đào tạo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.ADD)]
public void OnAdd(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingPlans)
{
View.Add();
}
}
/// <summary>
/// Thực hiện sửa thông tin trên kế hoạch đào tạo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.MODIFY)]
50. public void OnModify(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingPlans)
{
View.Modify();
}
}
/// <summary>
/// Thực hiện xóa thông tin trên kế hoạch đào tạo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.DELETE)]
public void OnDelete(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingPlans)
{
View.Delete();
}
}
/// <summary>
/// Thực hiện lưu thông tin trên kế hoạch đào tạo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.SAVE)]
public void OnSave(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingPlans)
{
View.Save();
}
}
/// <summary>
/// Thực hiện bỏ qua trên kế hoạch đào tạo
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[CommandHandler(CommandNames.CANCEL)]
public void OnCancel(object sender, EventArgs e)
{
if (WorkItem.Workspaces[WorkspaceNames.MainWorkspace].ActiveSmartPart is ViewTrain
ingPlans)
{
View.Cancel();
}
}
#endregion Phần code xử lý các sự kiện thêm, sủa, xóa
/// <summary>
51. /// This method is a placeholder that will be called by the view when it has been load
ed.
/// </summary>
public override void OnViewReady()
{
base.OnViewReady();
}
/// <summary>
/// Close the view
/// </summary>
public override void OnCloseView()
{
base.CloseView();
}
}
}