项目源码下载地址: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,调用创建的存储过程创建流水单号

      //获取流水单号
public override string GetDataSN(IDatabase db, string sDocCode, int sLength)
{
return sDocCode + db.ExecuteScalarSP<string>("sys_GetDataSN",
new { DataCode = sDocCode, Length = sLength });
}

修改下服务器时间获取函数:GetServerTime(不同数据库类型获取方式不一样)

      //获取系统时间,建议从服务器获取
public override DateTime GetServerTime(IDatabase db)
{
string sql = "SELECT GETDATE()";
return db.ExecuteScalar<DateTime>(sql);
}

2.使用生成器生成界面

1.先生成入库主表和明细表的Model

添加新项,选择 Model层生成

配置相关生成信息,并生成静态结构

生成的Model类如下,其中包含两个静态结构类,一个是主表tb_GoodsIn,一个是明细表tb_GoodsInDetail:

/**************************************************************************
====================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代码

   public 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如下(红色背景为新增的行)

       public 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类中

功能使用如下图,(保存验证不通过状态,即必填项为空)

当一个单据新建成功后会自动生成一个流水单号:

其中前缀和位数,都是我们在生成界面中指定的

Winform开发框架之单据窗体生成(主从表,流水单号)的更多相关文章

  1. Winform开发框架中工作流模块的业务表单开发

    在我们开发工作流的时候,往往需要设计到具体业务表单信息的编辑,有些是采用动态编辑的,有些则是在开发过程中处理的,各有各的优点,动态编辑的则方便维护各种各样的表单,但是数据的绑定及处理则比较麻烦,而自定 ...

  2. RDIFramework.NET V3.3 WinForm版新增订单管理主从表事例

    功能描述 无论什么系统,除了常规的单表处理外,主从表的应用都是非常普遍的,RDIFramework.NET V3.3 WinForm版本中新增了一个主从表的事例供大家参考.主从表的界面设计大同小异,主 ...

  3. Winform开发框架中工作流模块的表设计分析

    在较早博客随笔里面写过文章<Winform开发框架之简易工作流设计>之后,很久没有对工作流部分进行详细的介绍了,本篇继续这个主题,详细介绍其中的设计.实现及效果给大家,这个工作流在好几年前 ...

  4. Winform开发框架中工作流模块之申请单草稿处理

    在我们开发工作流模块的时候,有时候填写申请单过程中,暂时不想提交审批,那么可以暂存为草稿,以供下次继续填写或者提交处理,那么这个草稿的功能是比较实用的,否则对于一些填写内容比较多的申请单,每次要重填写 ...

  5. 参照企业微信审批业务,在Winform开发框架中工作流模块的实现业务审批

    目前微信的企业号已经切换到企业微信里面,这个是一个APP程序,提供了很丰富的企业应用,其中包括了业务审批处理,审批业务包括请假.报销.费用.出差等很多个审批场景,在Winform开发框架中工作流模块这 ...

  6. Winform开发框架的重要特性总结

    从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特性的加入完善,是经过了很多项目的总结归纳和升华,有些则是根据客户需要或者应用前景的需要进行的完善,整个Win ...

  7. Winform开发框架中工作流模块之审批会签操作

    在前面介绍了框架中工作流的几个开发过程,本篇随笔重点介绍一下日常审批环节中的具体处理过程,从开始创建表单,以及各个审批.会签过程的流转过程,希望大家对其中流程的处理有一个大概的印象. 1.请假申请表单 ...

  8. [转]Winform开发框架的重要特性总结

    本文转自:https://www.cnblogs.com/wuhuacong/p/3199829.html 从事Winform开发框架的研究和推广,也做了有几个年头了,从最初的项目雏形到目前各种重要特 ...

  9. Winform开发框架中工作流模块之审批会签操作(2)

    前面随笔介绍了请假申请单和报销申请单两个不同的业务表单的流程处理,一个是单表信息,一个包含明细的主从表信息,后者包含了条件流程的处理,在流程审批中,一般还有一种流程处理就是会签的操作,会签处理是几个审 ...

随机推荐

  1. Java程序设计 实验二 Java面向对象程序设计

    北京电子科技学院(BESTI) 实     验    报     告 课程:Java程序设计 班级:1353  姓名:李海空  学号:20135329 成绩:             指导教师:娄嘉鹏 ...

  2. setInterval对某个数值加加渐减

    decrease_time = setInterval(decrease_opacity_val,10); function decrease_opacity_val(){ showID.style. ...

  3. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  4. Difference between Stored Procedure and Function in SQL Server

    Stored Procedures are pre-compile objects which are compiled for first time and its compiled format ...

  5. mysql数据库、表、字段、记录:增、删、改、查

    /* 结构:数据库.表.字段.记录 操作:增删改查 */ -- 1.数据库:增删改查 create datebase if not exists jkxy; drop database if exis ...

  6. 阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue

    LinkedBlockingQueue: public class LinkedBlockingQueue<E> extends AbstractQueue<E> implem ...

  7. VMware workstaion上传虚拟机到VMware EXSI 5.5

    1.首先在VMware Workstation 文件 --- 连接VMware EXSI5.5服务器. 2.输入VMware EXSI 5.5服务器地址.用户名和密码. 3.右键Windows  7 ...

  8. JavaScript模块化开发整理

    在网上已经有很多关于模块化开发的文章了,这里还是按照自己的理解来整理一下. 随着项目文件的越来越大和需求的越来越贴近现实(我发现现在客户不如:一个领导说我要审批你们报上来的资料,系统发布以后用的还不错 ...

  9. sp_executesql

    execute相信大家都用的用熟了,简写为exec,除了用来执行存储过程,一般都用来执行动态Sql  sp_executesql,sql2005中引入的新的系统存储过程,也是用来处理动态sql的, 如 ...

  10. 关于为busybox设置setuid

    安卓root了,重启之后就没root权限了,于是想到了为 busybox 设置 setuid 来实现使用root的身份执行命令. 可是,不管用啊,还是提示没有权限.搜了一下 busybox setui ...