Business form development of the workflow module in the Winform development framework, winform Workflow
When developing workflows, we often need to design the editing of specific business form information, some adopt Dynamic editing, and some adopt processing during the development process, each having its own advantages, dynamic editing makes it easy to maintain various forms, but data binding and processing is troublesome. custom development makes data elastic and easy to modify and adjust. This document describes how to add a new business form in a workflow to quickly launch the approval service.
1. Business form base class inheritance
First, let's take a look at the correspondence between business forms. Generally, to create a business process, you must have a specific interface for creating a business form and an interface for viewing and processing forms.
For convenience, we try to reduce code writing as much as possible. We need to put most of the logic processing in the base class implementation, so that we can reduce a lot of coding and maintenance when adding a business form.
For example, the FrmAddApply class is defined as follows. We define some abstract interfaces for the following business form implementation.
/// <Summary> /// create the form base class of the Application Form /// </summary> public partial class FrmAddApply: baseForm {/// <summary> /// Form ID /// </summary> public string FormID {get; set ;} /// <summary> /// Application ID /// </summary> public string ApplyId {get; set;} public FrmAddApply () {InitializeComponent ();} /// <summary> /// function for displaying data (required for subclass) /// </summary> public virtual void DisplayData () {}/// <summary> /// function used to check the input of the control (required for subclass) /// </summary> /// <returns> </returns> public virtual bool CheckInput () {return true ;} /// <summary> /// save data in the editing state (required by subclass) /// </summary> /// <returns> </returns> public virtual bool SaveUpdated () {return true ;} /// <summary> /// save data in the new State (required by subclass) /// </summary> /// <returns> </returns> public virtual bool SaveAddNew () {return true ;}...................
In this way, we create a new business form. We only need to use the code generation tool to generate the required framework code at each layer, and then generate the Winform code, copy part of the interface and process the code to the subclass of the business form.
The following is a business form design for a leave application, as shown below.
We can see that this form can be adjusted after it is quickly generated using the code generation tool Database2Sharp. On this form editing interface, we only need to use part of the automatically generated code.
You only need to copy the code above for adding, updating, and displaying data.
For the FrmViewApply class, which is the basic class for viewing the application form, we need to load its custom interface control.
The following is the base class for viewing the application form, which encapsulates the relevant processing logic.
/// <Summary> /// this form is a basic class for the general view application interface. /// To reduce the workload of development-related pages, you only need to create a new form and inherit the form. Then, in the subform Form_Load function, initialize the corresponding application form display control. /// </Summary> public partial class FrmViewApply: BaseDock {// <summary> // Application ID /// </summary> public string ApplyId {get; set ;}//< summary> /// custom control of the Application Form /// </summary> public BaseUserControl ApplyControl {get; set ;} /// <summary> /// default constructor /// </summary> public FrmViewApply () {InitializeComponent ();} private void FrmViewApply_Load (object sender, EventArgs e) {if (! This. designMode) {InitToolBar () ;}/// <summary> // initialize the Application Form control /// </summary> protected virtual void InitApplyControl (BaseUserControl control) {if (control! = Null) {this. applyControl = control; this. applyControl. dock = DockStyle. fill; this. controls. add (control) ;}/// <summary> // print the Application Form control content (default call form printing) /// </summary> protected virtual void PrintApplyControl () {if (this. applyControl! = Null) {PrintFormHelper. print (this. applyControl, false) ;}/// <summary> /// Save the form as /// </summary> protected virtual void ApplySaveAs () {}/// <summary> /// initialize the buttons and status of the toolbar /// </summary> protected virtual void InitToolBar () {................ // The Implementation of the base class, controls when to approve and handle the request, and some common buttons }.................
The window for viewing the leave application is to inherit the FrmViewApply, as shown below.
/// <Summary> // view the form of the leave application // </summary> public partial class FrmViewLeave: FrmViewApply {private LeaveControl control = null; public FrmViewLeave () {InitializeComponent ();} private void FrmViewLeave_Load (object sender, EventArgs e) {// initialize the control and display it in the base-class form: control = new LeaveControl (); control. applyId = this. applyId; control. displayData (); base. initApplyControl (control );}}
This is the source code of all forms. The main content is in the user control class LeaveControl,
This control is mainly used to design the interface for editing the leave application form and copy the relevant data display code.
The related interface code is as follows.
/// <Summary> /// view the content display control of the leave application form /// </summary> public partial class LeaveControl: baseUserControl {/// <summary> /// Application ID /// </summary> public string ApplyId {get; set;} public LeaveControl () {InitializeComponent (); setReadOnly () ;}/// <summary> /// set the layout of the entire form to read-only and set the background color of read-only. /// </summary> private void SetReadOnly () {this. layoutControl1.OptionsView. isReadOnly = DevExpress. utils. defaboolean Boolean. True; this. layoutControl1.Appearance. controlReadOnly. backColor = Color. seaShell;} private void LeaveControl_Load (object sender, EventArgs e) {this. applyInfoControl1.ApplyId = this. applyId; this. applyInfoControl1.BindData ();} // <summary> // initialize the data dictionary // </summary> private void InitDictItem () {// initialization code} // <summary> // function for data display /// </summary> public void DisplayData () {InitDictItem (); // data dictionary Load (public) // because the application form entry is generally used for the application form, rather than the business data table, you can only pass in the ApplyId to obtain information if (! String. IsNullOrEmpty (ApplyId )){....................}
The form base class defined above can reduce the need for repeated encoding. We only need to use the most efficient interface generation, then, copy the code and adjust it to quickly generate different forms.
Every form is placed in a directory so that we can manage them well.
2. Dynamic Display and processing of business forms
The preceding section describes how to fill in and view business forms. Different Forms and create different business form interfaces are displayed on the application form approval page, this kind of dynamic processing allows you to create and display different business forms.
In my approval work, the form display interface is shown as follows. After you view a specific form, you can dynamically display different business Window Interfaces.
In addition, when creating a business form, we dynamically display all creation portals that can be displayed based on the database configuration information. Click the relevant button to dynamically call the corresponding form creation interface.
The portal for creating a process business form is as follows.
On the my approval page, dynamically create the corresponding view form code as follows.
/// <Summary> /// page control edit item operation /// </summary> private void wingridviewpager#oneditselected (object sender, EventArgs e) {// obtain the record ID and Form ID string ID = this. winGridViewPager1.gridView1. getFocusedRowCellDisplayText ("ID"); string FormId = string. concat (this. winGridViewPager1.gridView1. getFocusedRowCellValue ("FormId"); if (! String. IsNullOrEmpty (ID )&&! String. IsNullOrEmpty (FormId) {var formInfo = BLLFactory <BLL. Form>. Instance. FindByID (FormId); if (formInfo! = Null &&! String. isNullOrEmpty (formInfo. applyWin2) {try {// view the form according to the configuration, dynamically build and view the application form object FrmViewApply dlg = Assembly. getExecutingAssembly (). createInstance (formInfo. applyWin2) as FrmViewApply; if (dlg! = Null) {dlg. applyId = ID; dlg. onDataSaved + = new EventHandler (dlg_OnDataSaved); if (DialogResult. OK = dlg. showDialog () {BindData () ;}} catch (Exception ex) {LogHelper. error (ex); MessageDxUtil. showError (ex. message );}}}}
This code replaces the processing that requires manual creation of different objects.
var dlg = new FrmViewAssignWork(); dlg.ApplyId = ID; dlg.OnDataSaved += new EventHandler(dlg_OnDataSaved); if (DialogResult.OK == dlg.ShowDialog()) { BindData(); }
Similarly, for the creation and editing interface, we can dynamically create the relevant editing form interface in the same way, as shown in the following code.