在Winform中直接錄入表格數據和在Vue&Elment中直接錄入表格數據的比較

一般來說,錄入數據的時候,我們都採用在一個窗體介面中,根據不同內容進行錄入,但是有時候涉及主從表的數據錄入,從表的數據有時候為了錄入方便,也會通過表格控制項直接錄入。在Winform開發的時候,我們很多時候可以利用表格GridControl控制項來直接錄入數據;在BS的Vue&Elment前端項目中,也可以利用第三方組件vxe-table直接錄入表格數據。本篇隨筆對Winform和Vue&Elment中直接錄入數據進行分別的介紹和對比。

1、在Winform中直接錄入表格數據

我們可直接在底部進行數據的錄入,包括主表記錄和從表的明細記錄,可以一氣呵成的錄入並進行保存處理的,介面效果如下所示。

 GridView的主從關係需要設置好集合的映射關係,我們需要通過設置GridLevelNode集合實現主從表關係的處理的。

初始化從表的GridView2和主從表關係的程式碼如下所示

 

通過上面的初始化程式碼,指定了主從表的關係後,我們還需要對綁定的數據源進行一定的處理,才能夠在GridControl控制項上顯示主從表關係的記錄。

首先需要定義一個業務對象,用來存儲主從關係的記錄對象。

然後在BindData綁定數據的時候,程式碼處理如下即可。

數據保存的程式碼和前面的操作類似,我們需要分別對GridView1和GridView2的數據保存操作進行處理,如下程式碼所示。

GridView2的字典項目明細保存操作如下所示。

在流程管理裡面,對於具有主從明細的報銷業務表的數據處理,採用了下面的介面。

這個介面中對於從表數據的錄入處理程式碼如下所示。

        /// <summary>
        /// 初始化明細表的GridView數據顯示
        /// </summary>
        private void InitDetailGrid()
        {
            //初始清空列
            this.gridView1.Columns.Clear();
            //設置部分列隱藏
            this.gridView1.CreateColumn("ID", "編號").Visible = false;
            this.gridView1.CreateColumn("Header_ID", "主表編號").Visible = false;
            this.gridView1.CreateColumn("Apply_ID", "申請單編號").Visible = false;
            //添加下拉列表列,並綁定數據源
            this.gridView1.CreateColumn("FeeType", "費用類型", 100).CreateComboBox().BindDictItems("費用類型");
            //創建日期列並指定格式
            var OccurTime = this.gridView1.CreateColumn("OccurTime", "發生時間", 120).CreateDateEdit();
            OccurTime.EditMask = "yyyy-MM-dd HH:mm";
            OccurTime.DisplayFormat.FormatString = "yyyy-MM-dd HH:mm";
            //創建數值列
            this.gridView1.CreateColumn("FeeAmount", "費用金額").CreateSpinEdit();
            //創建備註列
            this.gridView1.CreateColumn("FeeDescription", "費用說明", 200).CreateMemoEdit();

            //初始化GridView,可以新增列
            this.gridView1.InitGridView(GridType.NewItem, false, EditorShowMode.MouseDownFocused, "");
            //轉義列內容顯示
            this.gridView1.CustomColumnDisplayText += new CustomColumnDisplayTextEventHandler(gridView1_CustomColumnDisplayText);
            //處理單元格的樣式
            this.gridView1.RowCellStyle += new RowCellStyleEventHandler(gridView1_RowCellStyle);
            //不允許頭部排序
            this.gridView1.OptionsCustomization.AllowSort = false;
            //繪製序號
            this.gridView1.CustomDrawRowIndicator += (s, e) =>
            {
                if (e.Info.IsRowIndicator && e.RowHandle >= 0)
                {
                    e.Info.DisplayText = (e.RowHandle + 1).ToString();
                }
            };

            //對輸入單元格進行非空校驗
            this.gridView1.ValidateRow += delegate(object sender, ValidateRowEventArgs e)
            {
                var result = gridControl1.ValidateRowNull(e, new string[]
                {
                    "FeeType"
                });
            };
            //新增行的內容初始化
            this.gridView1.InitNewRow += (s, e) =>
            {
                gridView1.SetRowCellValue(e.RowHandle, "ID", Guid.NewGuid().ToString());
                gridView1.SetRowCellValue(e.RowHandle, "Header_ID", tempInfo.ID);
                gridView1.SetRowCellValue(e.RowHandle, "Apply_ID", tempInfo.Apply_ID);
                gridView1.SetRowCellValue(e.RowHandle, "OccurTime", DateTime.Now);
            };
        }

保存處理的時候,我們獲取明細列表,在寫入從表記錄後,繼續保存明細列表即可。

        /// <summary>
        /// 獲取明細列表
        /// </summary>
        /// <returns></returns>
        private List<ReimbursementDetailInfo> GetDetailList()
        {
            var list = new List<ReimbursementDetailInfo>();
            for (int i = 0; i < this.gridView1.RowCount; i++)
            {
                var detailInfo = gridView1.GetRow(i) as ReimbursementDetailInfo;
                if (detailInfo != null)
                {
                    list.Add(detailInfo);
                }
            }
            return list;
        }

        /// <summary>
        /// 新增狀態下的數據保存
        /// </summary>
        /// <returns></returns>
        public override bool SaveAddNew()
        {
            ReimbursementInfo info = tempInfo;//必須使用存在的局部變數,因為部分資訊可能被附件使用
            SetInfo(info);
            info.Creator = base.LoginUserInfo.ID;
            info.CreateTime = DateTime.Now;

            try
            {
                #region 新增數據

                bool succeed = BLLFactory<Reimbursement>.Instance.Insert(info);
                if (succeed)
                {
                    //可添加其他關聯操作
                    var list = GetDetailList();
                    foreach(var detailInfo in list)
                    {
                        BLLFactory<ReimbursementDetail>.Instance.InsertUpdate(detailInfo, detailInfo.ID);
                    }
                    
                    return true;
                }
                #endregion
            }
            catch (Exception ex)
            {
                LogTextHelper.Error(ex);
                MessageDxUtil.ShowError(ex.Message);
            }
            return false;
        }

有時候,我們可以根據列表設置一些下拉列表欄位,如下面所示。

 或者禁用某些欄位的錄入,如下所示。

 

 

2、在Vue&Elment中直接錄入表格數據

我在隨筆《在Vue前端介面中,幾種數據表格的展示處理,以及表格編輯錄入處理操作》中介紹過在Vue前端介面中利用vxe-table表格組件實現數據的直接錄入的。

vxe-table地址:

//xuliangzhan_admin.gitee.io/vxe-table/#/table/start/install

//github.com/x-extends/vxe-table

我們來看看它的常規使用程式碼,以及介面效果

 如果需要錄入新記錄,通事件處理添加一個行即可。 

 

這裡繼續介紹vxe-table表格組件的直接錄入處理,特別是相關字典列表,以及級聯處理操作。

例如,對於資產領用的明細清單處理,前端介面程式碼如下所示。

  <el-col :span="24">
    <el-form-item label="明細清單">
      <div>
        <vxe-toolbar>
          <template #buttons>
            <vxe-button status="primary" content="新增" @click="insertEvent" />
            <vxe-button status="warning" content="刪除" @click="removeSelectEvent" />
          </template>
        </vxe-toolbar>
        <vxe-table ref="xTable" border show-overflow keep-source resizable show-overflow :data="list"
          :edit-config="{trigger: 'click', mode: 'row', showStatus: true}">
          <vxe-column type="checkbox" width="60" />
          <vxe-column field="assetName" title="資產名稱"
            :edit-render="{name: 'input', events: {focus: assetNameFocusEvent}}" />
          <vxe-column field="assetCode" title="資產編碼" :visible="true" />
          <vxe-column field="lyDept" title="使用部門"
            :edit-render="{name: '$select', options: deptList, events: {change: deptChangeEvent}}" />
          <vxe-column field="usePerson" title="使用人"
            :edit-render="{name: '$select', options: usePersonList}" />
          <vxe-column field="keepAddr" title="存放地點" :edit-render="{name: 'input', attrs: {type: 'text'}}" />
          <vxe-column field="unit" title="單位" :edit-render="{name: 'input', attrs: {type: 'text'}}" />
          <vxe-column field="price" title="單價(元)"
            :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" />
          <vxe-column field="totalQty" title="數量"
            :edit-render="{name: '$input', props: {type: 'integer'}}" />
          <vxe-column field="totalAmount" title="金額(元)"
            :edit-render="{name: '$input', props: {type: 'float', digits: 2}}" />
          <vxe-column field="note" title="備註" :edit-render="{name: 'input', attrs: {type: 'text'}}" />
        </vxe-table>
      </div>
    </el-form-item>
  </el-col>

我們在選擇資產名稱的時候,通過焦點事件彈出一個資產選擇的對話框處理,如下所示的程式碼

events: {focus: assetNameFocusEvent}}

然後在事件中,我們彈出一個對話框來

    assetNameFocusEvent ({ row, column }) {
      this.currentRow = row
      this.$refs.asset.show()
    },

 如果是下拉列表,我們可以綁定自己的數據源即可,如下面介面部門列表所示。

 

 

 

  如果需要錄入數據中的列表進行聯動處理,如在事件ptypeChangeEvent中更新pnameList可以實現

<vxe-column field="attr3" title="Project type"
    :edit-render="{name: '$select', options: ptypeList, props: {clearable: true}, events: {change: ptypeChangeEvent}}"></vxe-column>
<vxe-column field="attr4" title="Project name" :formatter="formatPanmeLabel"
    :edit-render="{name: '$select', options: pnameList, props: {clearable: true}}"></vxe-column>
// 更新級聯選項列表
updatePnameList (row) {
  let ptype = row.attr3
  let pnameList = []
  if (ptype) {
    let item = this.cachePnameList.find(item => item.ptype === ptype)
    if (item) {
      pnameList = item.pnameList
    } else {
      // 模擬後台數據
      Array.from(new Array(XEUtils.random(3, 8))).forEach((item, index) => {
        pnameList.push({
          label: `${ptype}-名稱${index}`,
          value: `${ptype}_${index}`
        })
      })
      this.cachePnameList.push({ ptype, pnameList })
    }
  }
  this.pnameList = pnameList
},
ptypeChangeEvent ({ row }) {
  // 類型切換時更新級聯的下拉數據
  row.attr4 = ''
  this.updatePnameList(row)
},

對於Vxe-table組件的列,它的edit-render標記它的類型處理。

 列的類型可以是普通的input,也可以是其他類型,如數值類型,下拉列表,日期等類型,下面一些案例程式碼供參考。

<vxe-column type="seq" width="60" />
<vxe-column field="name" title="Name" :edit-render="{name: 'input', attrs: {type: 'text'}}"></vxe-column>
<vxe-column field="nickname" title="Role"
    :edit-render="{name: 'input', attrs: {type: 'text', placeholder: '請輸入昵稱'}}"></vxe-column>
<vxe-column field="sex" title="Sex"
    :edit-render="{name: '$select', options: sexList}"></vxe-column>
<vxe-column field="sex2" title="多選下拉"
    :edit-render="{name: '$select', options: sexList, props: {multiple: true}}"></vxe-column>
<vxe-column field="num1" title="Amount"
    :edit-render="{name: '$input', props: {type: 'float', digits: 2}}"></vxe-column>
<vxe-column field="date12" title="Date"
    :edit-render="{name: '$input', props: {type: 'date', placeholder: '請選擇日期'}}"></vxe-column>
<vxe-column field="date13" title="Week"
    :edit-render="{name: '$input', props: {type: 'week', placeholder: '請選擇日期'}}"></vxe-column>

<vxe-column field="age" title="ElInputNumber"  width="160" :edit-render="{}">
  <template #edit="{ row }">
    <el-input-number v-model="row.age" :max="35" :min="18"></el-input-number>
  </template>
 </vxe-column>

其中列的Type類型如下定義所示,可以選擇特定的類型。

如果input類型,那麼可以選擇各種格式的輸入介面,如下所示。

具體的資訊可以查看控制項的API說明://xuliangzhan_admin.gitee.io/vxe-table/#/column/api

以上就是關於在Winform中直接錄入表格數據和在Vue&Elment中直接錄入表格數據的介紹,總體來說都是比較方便的,數據可以分開主從表錄入,也可以一併提供數據對象給後台一併處理,具體根據情況處理即可。