項目源碼下載地址:https://github.com/GarsonZhang/GZFramework.Demo
前言
1.在開始本節前請先重置代碼為 chapter-03-start
懶人地址:https://github.com/GarsonZhang/GZFramework.ShareDemo/tree/chapter-03-start
2.創建表(商品入庫主表/明細)
創建腳本目錄:數據庫腳本/Chapter-03新建商品入庫表(主從表).sql
3.新建生成單據流水號所需的表和存儲過程
創建腳本目錄:數據庫腳本/Chapter-03新建商品入庫表(主從表).sql
生成器生成界面
1.修改相關底層生成規則
修改文件:_GZFramework.Demo.Business.Base.dalBase.cs
修改流水單號生成函數:GetDataSN,調用創建的存儲過程創建流水單號
View Code//獲取流水單號 public override string GetDataSN(IDatabase db, string sDocCode, int sLength) { return sDocCode + db.ExecuteScalarSP<string>("sys_GetDataSN", new { DataCode = sDocCode, Length = sLength }); }修改下服務器時間獲取函數:GetServerTime(不同數據庫類型獲取方式不一樣)
View Code//獲取系統時間,建議從服務器獲取 public override DateTime GetServerTime(IDatabase db) { string sql = "SELECT GETDATE()"; return db.ExecuteScalar<DateTime>(sql); }
2.使用生成器生成界面
1.先生成入庫主表和明細表的Model
添加新項,選擇 Model層生成
配置相關生成信息,並生成靜態結構
生成的Model類如下,其中包含兩個靜態結構類,一個是主表tb_GoodsIn,一個是明細表tb_GoodsInDetail:
View Code/************************************************************************** ====================GZFramwork【Winfrom快速開發框架】==================== -- 作者:Garson_Zhang QQ:382237285 QQ交流群:288706356 -- 博客地址:http://www.cnblogs.com/GarsonZhang/ -- CLR版本: 4.0.30319.42000 -- 創建時間:2015-09-17 10:52:26 -- 創建年月:2015 **************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using GZFramework.DB.ModelAttribute; namespace _GZFramework.Demo.Models { /// <summary> /// ORM模型, 數據表:tb_GoodsInDetail /// GZFrameworkCodeGenerate代碼生成器自動生成 /// 時間:2015-09-17 10:52 /// </summary> [ModelStruct(tb_GoodsInDetail._TableName)] public sealed class tb_GoodsInDetail { public const string _TableName = "tb_GoodsInDetail"; /// <summary> /// 自增字段 /// </summary> [ModelPrimaryKey] public const string isid = "isid"; /// <summary> /// 單據號碼 /// </summary> [ModelForeignKey] public const string DocNo = "DocNo"; /// <summary> /// 時間戳 /// </summary> [ModelRowversion] public const string rowversion = "rowversion"; /// <summary> /// 商品編號 /// </summary> [ModelEditField] public const string GoodsID = "GoodsID"; /// <summary> /// 商品名稱 /// </summary> [ModelEditField] public const string GoodsName = "GoodsName"; /// <summary> /// 存放倉庫 /// </summary> [ModelEditField] public const string SID = "SID"; /// <summary> /// 存放倉位 /// </summary> [ModelEditField] public const string AID = "AID"; /// <summary> /// 數量 /// </summary> [ModelEditField] public const string Qty = "Qty"; /// <summary> /// 備注 /// </summary> [ModelEditField] public const string Remark = "Remark"; /// <summary> /// 創建人 /// </summary> [ModelEditField] public const string CreateUser = "CreateUser"; /// <summary> /// 創建日期 /// </summary> [ModelEditField] public const string CreateDate = "CreateDate"; /// <summary> /// 修改人 /// </summary> [ModelEditField] public const string LastUpdateUser = "LastUpdateUser"; /// <summary> /// 修改日期 /// </summary> [ModelEditField] public const string LastUpdateDate = "LastUpdateDate"; } /// <summary> /// ORM模型, 數據表:tb_GoodsIn /// GZFrameworkCodeGenerate代碼生成器自動生成 /// 時間:2015-09-17 10:52 /// </summary> [ModelStruct(tb_GoodsIn._TableName)] public sealed class tb_GoodsIn { public const string _TableName = "tb_GoodsIn"; /// <summary> /// 自增字段 /// </summary> public const string isid = "isid"; /// <summary> /// 時間戳 /// </summary> [ModelRowversion] public const string rowversion = "rowversion"; /// <summary> /// 單據號碼 /// </summary> [ModelPrimaryKey] public const string DocNo = "DocNo"; /// <summary> /// 入庫日期 /// </summary> [ModelEditField] public const string DocDate = "DocDate"; /// <summary> /// 入庫人 /// </summary> [ModelEditField] public const string OperationUser = "OperationUser"; /// <summary> /// 供應商 /// </summary> [ModelEditField] public const string Supplier = "Supplier"; /// <summary> /// 種類 /// </summary> [ModelEditField] public const string GoodsType = "GoodsType"; /// <summary> /// 備注 /// </summary> [ModelEditField] public const string Remark = "Remark"; /// <summary> /// 創建人 /// </summary> [ModelEditField] public const string CreateUser = "CreateUser"; /// <summary> /// 創建日期 /// </summary> [ModelEditField] public const string CreateDate = "CreateDate"; /// <summary> /// 修改人 /// </summary> [ModelEditField] public const string LastUpdateUser = "LastUpdateUser"; /// <summary> /// 修改日期 /// </summary> [ModelEditField] public const string LastUpdateDate = "LastUpdateDate"; } }2.生成界面:
添加新項選擇功能窗體生成
配置主表生成信息:
配置明細表生成信息:注意先添加明細表
生成以后的窗體如下:
在frmGoodsIn.cs類中添加補充缺失的引用
生成的frmGoodsIn.cs代碼
View Codepublic partial class frmGoodsIn : frmBaseDataBusiness { public frmGoodsIn() { InitializeComponent(); this.Load += frm_Load; //實例化必須,bllBusinessBase必須替換為bll層自己繼承的子類(指定正確的dal.DBCode),建議封裝重寫到項目bll層 //_bll = new bllBusinessBase(typeof(tb_GoodsIn),"GI",6,typeof(tb_GoodsInDetail)); _bll = new bllBaseSystem(typeof(tb_GoodsIn), "GI", 6, typeof(tb_GoodsInDetail)); } private void frm_Load(object sender, EventArgs e) { _SummaryView = gvMainData;//必須賦值 base.AddControlsOnAddKey(txtDocDate, txtOperationUser); base.AddControlsOnlyRead(txtDocNo, txtCreateUser, txtCreateDate, txtLastUpdateUser, txtLastUpdateDate); } //查詢 private void btn_Search_Click(object sender, EventArgs e) { var p = ParametersProvide.New(); if (!String.IsNullOrEmpty(txts_DocNo.Text)) p.AddParameter("@DocNo", 0, txts_DocNo.Text); if (!String.IsNullOrEmpty(txts_DocDate.Text)) p.AddParameter("@DocDate", 0, txts_DocDate.Text); if (!String.IsNullOrEmpty(txts_OperationUser.Text)) p.AddParameter("@OperationUser", 0, txts_OperationUser.Text); if (!String.IsNullOrEmpty(txts_Supplier.Text)) p.AddParameter("@Supplier", 0, txts_Supplier.Text); if (!String.IsNullOrEmpty(txts_GoodsType.Text)) p.AddParameter("@GoodsType", 0, txts_GoodsType.Text); DataTable dt = _bll.Search(p); gcMainData.DataSource = dt; if (gvMainData.RowCount < 100)//行數過多會很耗時 gvMainData.BestFitColumns(); } //清空條件 private void btn_Clear_Click(object sender, EventArgs e) { LibraryTools.DoClearPanel(LC_Search); } //保存前檢查 protected override bool ValidateBeforSave() { bool Validate = true & LibraryTools.IsNotEmpBaseEdit(txtDocDate, "入庫日期不能為空!") & LibraryTools.IsNotEmpBaseEdit(txtOperationUser, "入庫人不能為空!"); Validate = Validate & !gv_Detail_tb_GoodsInDetail.HasColumnErrors & gv_Detail_tb_GoodsInDetail.ValidateEditor(); return Validate; } private void gv_Detail_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e) { string TableName = (sender as DevExpress.XtraGrid.Views.Grid.GridView).GridControl.DataSource.ToString(); (sender as DevExpress.XtraGrid.Views.Grid.GridView).SetRowCellValue(e.RowHandle, _bll.DetailModel[TableName].ForeignKey, EditData.Tables[_bll.SummaryModel.TableName].Rows[0][_bll.SummaryModel.PrimaryKey]); } private void gc_Detail_EmbeddedNavigator_ButtonClick(object sender, DevExpress.XtraEditors.NavigatorButtonClickEventArgs e) { if (e.Button.ButtonType == DevExpress.XtraEditors.NavigatorButtonType.Remove) { e.Handled = Msg.AskQuestion("是否確定要刪除選中行?") == false; } } private void gv_Detail_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e) { var view = sender as DevExpress.XtraGrid.Views.Grid.GridView; if (Object.Equals(view.FocusedColumn.Tag, "NotNull")) { if (Object.Equals(string.Empty, e.Value) || Object.Equals(null, e.Value) || Object.Equals(DBNull.Value, e.Value)) { e.Valid = false; e.ErrorText = view.FocusedColumn.Caption + "不能為空!"; } } } private void gv_Detail_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e) { var view = sender as DevExpress.XtraGrid.Views.Grid.GridView; bool V = true; foreach (DevExpress.XtraGrid.Columns.GridColumn column in view.Columns) { if (Object.Equals(column.Tag, "NotNull")) { if (String.IsNullOrEmpty(view.GetFocusedRowCellDisplayText(column))) { view.SetColumnError(column, column.Caption + "不能為空!"); V = V & false; } } } e.Valid = V; } private void gv_Detail_InvalidRowException(object sender, DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs e) { //去掉驗證行失敗時彈出的確認框 e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction; } #region 其他常用 //綁定明細頁數據 public override void DoBoundEditData() { base.DoBoundEditData(); gc_Detail_tb_GoodsInDetail.DataSource = EditData.Tables[tb_GoodsInDetail._TableName]; //其他綁定 //LibraryTools.DoBindingEditorPanel(pan_Summary, EditData.Tables[_bll.SummaryTableName], "txt"); //txxtPassword.EditValue = EditData.Tables[_bll.SummaryTableName].Rows[0][dt_MyUser.Password]; //gc_Detail.DataSource = EditData.Tables[dt_MyUserRole._TableName]; } //獲得詳細數據,明細也 public override DataSet GetEditData(string KeyValue) { return base.GetEditData(KeyValue); } /// <summary> /// 設置窗體的基礎權限從FunctionAuthorityCommon類中取,例如(默認): /// return FunctionAuthorityCommon.VIEW//查看 /// + FunctionAuthorityCommon.ADD//新增 /// + FunctionAuthorityCommon.EDIT//修改 /// + FunctionAuthorityCommon.DELETE//刪除 /// + FunctionAuthorityCommon.Save//保存 /// + FunctionAuthorityCommon.Cancel;//取消 /// </summary> protected override int CurrentAuthority { get { return base.CurrentAuthority; } } //自定義窗體權限按鈕 public override void IniButton() { base.IniButton(); } //窗體狀態改變后 protected override void DataStateChanged(FormDataState NewState) { base.DataStateChanged(NewState); } //窗體狀態改時 protected override void DataStateChanging(FormDataState OldState, FormDataState NewState) { base.DataStateChanging(OldState, NewState); } /// <summary> /// 設置按鈕可用狀態,如果已經在ControlOnlyReads或SetControlAccessable中添加,這里不需要重新設置 /// </summary> /// <param name="Edit"></param> protected override void SetControlAccessable(bool Edit) { //LibraryTools.SetControlAccessable(tp_Edit, Edit); base.SetControlAccessable(Edit); } #endregion #region 操作事件,不需要的可以刪除 /// <summary> /// 查詢 /// </summary> public override void DoView(object sender) { base.DoView(sender); } /// <summary> /// 刷新 /// </summary> public override void DoRefresh(object sender) { base.DoRefresh(sender); } /// <summary> /// 新增 /// </summary> public override void DoAdd(object sender) { base.DoAdd(sender); } /// <summary> /// 刪除 /// </summary> public override void DoDelete(object sender) { base.DoDelete(sender); } /// <summary> /// 修改 /// </summary> public override void DoEdit(object sender) { base.DoEdit(sender); } /// <summary> /// 保存 /// </summary> public override void DoSave(object sender) { base.DoSave(sender); } /// <summary> /// 保存並關閉 /// </summary> public override void DoSaveAndClose(object sender) { base.DoSaveAndClose(sender); } /// <summary> /// 審核 /// </summary> public override void DoApproval(object sender) { base.DoApproval(sender); } /// <summary> /// 返回取消 /// </summary> public override void DoCancel(object sender) { base.DoCancel(sender); } /// <summary> /// 打印預覽 /// </summary> public override void DoPreview(object sender) { base.DoPreview(sender); } /// <summary> /// 導出數據 /// </summary> public override void DoExport(object sender) { base.DoExport(sender); } #endregion }
3.修改Management如下(紅色背景為新增的行)
View Codepublic Management() { FunctionCollection.AddFunction(typeof(frmMyUser), "用戶管理", "Function_Account");FunctionCollection.AddFunction(typeof(frmGoodsIn), "商品入庫", "");}
運行軟件,如下圖所示:
商品入庫出現,圖片可以在Management.cs中第三個參數設置,注意圖片尺寸是64x64,放在images目錄下,后綴應該是 _64x64,比如用戶管理第三個參數為Function_Accouint,其在images下的圖片全名應該為:Function_Accouint_64x64.png
獲取圖片的相應方法在_GZFramework.Demo.Library.MyClass.LoadUIImage類中
功能使用如下圖,(保存驗證不通過狀態,即必填項為空)
當一個單據新建成功后會自動生成一個流水單號:
其中前綴和位數,都是我們在生成界面中指定的