主从表演练之采购单2-个性化调整
在 主从表演练之采购单 中,我们已经快速的生成(创建)了一个标准的主从表窗体功能,我们接下来还需要对功能进行一些调整,
比如,状态,结算方式,供应商,要改为 选择,单据日期要改为日期类型
订单状态
1)编辑页面中订单状态控件类型改为 LookUpEdit
如果数据绑定模式选择了 辅助控件
的方式,修改了控件类型后,还需要对控件进行数据绑定
不然,控件无法和数据关联
2)新增订单状态数据绑定方法
在Model层中定义订单状态枚举
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WinFrameworkDemo.Models
{
public enum DocType
{
挂起 = 0,
提交 = 1,
废弃 = -1
}
}
然后再 WinFramework.Library.DataBinderTools.cs
中新增一个静态方法,绑定 订单状态数据
/// <summary>
/// 绑定订单类型,挂起,提交,撤销
/// </summary>
/// <param name="lue"></param>
public static void BoundDocType(LookUpEdit lue)
{
BoundDocType(lue.Properties);
}
/// <summary>
/// 绑定订单类型,挂起,提交,撤销
/// </summary>
/// <param name="lue"></param>
public static void BoundDocType(RepositoryItemLookUpEdit lue)
{
DataTable dt = Tools.EnumToDataTable(typeof(WinFrameworkDemo.Models.DocType), "Name", "Value");
InitializeControl(lue, new string[] { "状态" }, new string[] { "Name" });
BoundDatabase(lue, dt, false, false, "Name", "Value");
}
3)在窗体代码中绑定状态数据源
在窗体frm_Load
事件中绑定 编辑页面 订单状态控件的数据源
//绑定订单状态
DataBinderTools.Bound.BoundDocType(txtDocType);
4)运行项目看看效果
看到状态字段已经变成了选择
修改状态下的展示
订单状态查询表格数据绑定
现在我们发现,在查询表格中,显示状态还是只显示值,而不是显示描述
我们期望的是,像编辑页面那样,显示出对应的文本描述
1)修改状态列,选择LookUpEdit
修改控件名字为lueDocType
2)窗体Load事件中添加数据绑定
//绑定订单状态 查询表格
DataBinderTools.Bound.BoundDocType(lueDocType);
3)测试
查询界面中,表格中状态字段已经显示出文本值
结算方式
结算方式选择在公共字典中配置
1)公共字典中添加 结算方式
修改 WinFrameworkDemo.Business.CustomerEnum.EnumCommonDicData
增加一个枚举值:结算方式
namespace WinFrameworkDemo.Business.CustomerEnum
{
/// <summary>
/// 基础字典
/// </summary>
public enum EnumCommonDicData
{
产品材质 = 1,
单位,
结算方式,
配送方式,
//扩展以下3个类型
付款方式,
货币类型
}
}
运行项目
在 基础字典 → 公共字典 功能中
看到字典类型已经添加了结算方式的类型,完善一下结算方式的明细数据
2)修改结算方式控件类型
把结算方式控件类型改为ComboBoxEdit
如果数据绑定模式选择了 辅助控件
的方式,修改了控件类型后,还需要对控件进行数据绑定
不然,控件无法和数据关联
3)窗体Load事件中绑定结算状态数据源
// 绑定结算方式
WinFramework.Library.DataBinderTools.Bound.BoundCommonDictDataName(txtPayType, EnumCommonDicData.结算方式, false);
框架已经集成实现了公共字典数据源的统一绑定方法,所以这里我们不用向订单状态那样去扩展DataBinderTools的方法
4)测试
新增
编辑
供应商
供应商我们期望从 基础字典 → 供应商资料 中获取
通过弹窗方式选择
1)添加SearchButton控件
把编辑页面 供应商控件改为 SearchButton
工具箱中拖拽一个 SearchButtonEdit到窗体中,然后替换掉供应商的控件
调整后界面
设置属性
2)弹窗功界面设计
在 WinFramework.Library.SearchEditDialog 中添加Windows窗体命名为 frmSearchDialog_Supplier
frmSearchDialog_Supplier
继承自 SearchTextEdit.frmDialogDataSearchBase
frmSearchDialog_Supplier.cs 主要代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WinFrameworkDemo.Business.Data;
namespace WinFramework.Library.SearchEditDialog
{
public partial class frmSearchDialog_Supplier : SearchTextEdit.frmDialogDataSearchBase
{
BLL_Supplier bll;
public frmSearchDialog_Supplier()
{
InitializeComponent();
bll = new BLL_Supplier();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
if (!String.IsNullOrEmpty(SearchCode))
{
txt_Code.Text = SearchCode;
}
LoadData();
if (DataSource != null && DataSource.Rows.Count > 0)
gridView1.Focus();
else
txt_Code.Focus();
}
public DataTable DataSource;
private void btn_Search_Click(object sender, EventArgs e)
{
LoadData();
}
void LoadData()
{
DataSource = bll.Search(txt_Code.Text, "", "");
gridControl1.DataSource = DataSource;
gridView1.BestFitColumns();
}
//处理数据
public override object GetSelect(out object EditValue, out bool Success)
{
EditValue = null;
Success = false;
DataRow dr = gridView1.GetFocusedDataRow();
if (dr == null) return null;
EditValue = dr[WinFrameworkDemo.Models.dt_Data_Supplier.SupplierName];
Success = true;
return dr;
}
//验证是否选择数据
protected override bool ValidateForSelect()
{
return gridView1.FocusedRowHandle >= 0;
}
//验证返回数据是否正确,
protected override bool ValidateObject(object obj)
{
return obj != null;
}
private void gridView1_DoubleClick(object sender, EventArgs e)
{
doSelect();
}
}
}
BLL_Supplier
代码
public class BLL_Supplier : Base.bllBaseUserCommon
{
public BLL_Supplier()
: base(typeof(dt_Data_Supplier))
{
}
public DataTable Search(string Code, string ZJM, string SupplierName)
{
string spname = "usp_Supplier_Search";
SqlParameterProvider p = new SqlParameterProvider();
if (!String.IsNullOrEmpty(Code)) p.AddParameter("@Code", SqlDbType.VarChar, 20, Code);
if (!String.IsNullOrEmpty(ZJM)) p.AddParameter("@ZJM", SqlDbType.VarChar, 20, ZJM);
if (!String.IsNullOrEmpty(SupplierName)) p.AddParameter("@SupplierName", SqlDbType.VarChar, 20, SupplierName);
return dal.DBHelper.GetTableSP(spname, Models.dt_Data_Supplier._TableName, p);
}
}
3)弹窗和SearchButtonEdit 绑定
在窗体Load事件中添加供应商弹窗选择绑定
//供应商
txtSupplierName.Properties.FormShowDialog = typeof(WinFramework.Library.SearchEditDialog.frmSearchDialog_Supplier);
txtSupplierName.Properties.OnSelectChanged += txtSupplierName_OnSelectChanged;
//选择供应商事件代码
private bool txtSupplierName_OnSelectChanged(DevExpress.XtraEditors.BaseEdit sender, object SelectObj)
{
if (SelectObj is DataRow)
{
DataRow dr = SelectObj as DataRow;
EditData.Tables[tb_PO._TableName].Rows[0][tb_PO.SupplierName] = sender.EditValue;
EditData.Tables[tb_PO._TableName].Rows[0][tb_PO.SupplierID] = dr[dt_Data_Supplier.SupplierID];
EditData.Tables[tb_PO._TableName].Rows[0][tb_PO.SupplierAddress] = dr[dt_Data_Supplier.SupplierAddress];
EditData.Tables[tb_PO._TableName].Rows[0][tb_PO.SupplierPhone] = dr[dt_Data_Supplier.Phone];
EditData.Tables[tb_PO._TableName].Rows[0].EndEdit();
}
return true;
}
4)测试
点击供应商右边的选字,就弹出了供应商选择弹窗,双击选择后,回填数据
设置只读
经过一些列更改调整后,选择编辑页面供应商编号不应该再支持修改的
设置供应商编号只读
在frm_Load
事件中,base.AddControlsOnlyRead()方法,添加供应商编号控件
// 设置只读
base.AddControlsOnlyRead(this.txtSupplierID, this.txtCreateUser, this.txtCreateDate, this.txtLastUpdateUser, this.txtLastUpdateDate);
这样,供应商编号控件,就变成了只读控件,不允许更改了,选择了供应商之后,自动赋值
单据编号自动生成
最后,我们配置单据编号自动生成,生成唯一的流水单号
1)添加采购单流水单号模型
WinFrameworkDemo.Models.DocSN中添加采购单流水单号模型类 SN_PONO
继承 WinFrameworkDemo.Models.Sys.ModelDocNo
SN_PONO.cs 代码
using WinFrameworkDemo.Models.Sys;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WinFrameworkDemo.Models.DocSN
{
public class SN_PONO : ModelDocNo
{
public SN_PONO()
{
this.DocCode = "PONO";
this.DocName = "采购单编号";
this.DocHeader = "P";
this.Length = 3;
this.DocType = WinFrameworkDemo.Models.DocSN.GenerateDocSNRule.Year_Month;
}
}
}
2)修改 BLL层的 BLLDemo_PO.cs 代码
WinFrameworkDemo.Business.Demo.BLLDemo_PO.cs 中 添加 采购单流水单号模型配置
using WinFrameworkDemo.Models;
namespace WinFrameworkDemo.Business.Demo
{
public partial class BLLDemo_PO
: Base.bllBaseUserCommon<Models.DocSN.SN_PONO>
{
public BLLDemo_PO()
: base(typeof(tb_PO))
{
}
}
}
3)调整采购单功能
WinframeworkDemo.Test.frmPO功能调整
取消单据编号数据验证
流水单号自动生成单据号码,所以这里不再需要验证
设置单据编号只读
frm_Load事件中,
- AddControlsOnAddKey方法中 如果有 txtDocNo参数,则取消
- AddControlsOnlyRead方法添加 txtDocNo参数
修改前
修改后
4)测试
略
报表打印
1)窗体权限设置 FormAuthority
添加报表打印权限,FunctionAuthorityCommon.PREVIEW
protected override int FormAuthority
{
get
{
return base.FormAuthority + FunctionAuthorityCommon.PREVIEW;
}
}
2)报表模板设计
报表模板文件存放位置:程序目录 \ reports \ ***.frx
3)重写功能窗体的 DoPreview方法
/// <summary>
/// 打印预览
/// </summary>
protected override void DoPreview(object sender)
{
if (gvMainData.FocusedRowHandle < 0) return;
string docno = gvMainData.GetFocusedRowCellValue(tb_PO.DocNo) + "";
DataSet ds = bll.DoGetDocData(docno);
bool v = ((int)Models.DocType.提交).Equals(ds.Tables[tb_PO._TableName].Rows[0][tb_PO.DocType]);
if (v == false)
{
Msg.Warning("当前单据未提交,不允许打印!");
return;
}
string filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Reports\\rpt_PO.frx");
RptCommonMainDetail rptHelper = new RptCommonMainDetail(this, filename, ds.Tables[tb_PO._TableName], ds.Tables[tb_PODetail._TableName]);
rptHelper.BeforePrepare += RptHelper_BeforePrepare;
ReportServer.frmRptPreview.ShowForm(rptHelper);
}
private void RptHelper_BeforePrepare(global::FastReport.Report rpt)
{
var total = (decimal)(rpt.GetDataSource("D").Reference as DataTable).Compute($"SUM({Models.tb_PODetail.Amount})", "1=1");
string str = WinFramework.Common.RMBConverter.toRMB(total);
var PrintUser = rpt.Parameters.FindByName("TotalAmount");
if (PrintUser != null) PrintUser.Value = str;
}
4)功能测试
进入 采购单
功能,选择
一条记录,然后点击操作区的打印预览
按钮