欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Winform] DataGridView辅助类

程序员文章站 2022-06-08 15:44:18
...
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;

namespace Dxq.Foundation.Forms
{
    /// <summary>
    ///     DataGridView助手.
    /// </summary>
    public class DataGridViewAssistant
    {
        /// <summary>
        ///     DataGridView
        /// </summary>
        private readonly DataGridView _dgv;

        /// <summary>
        ///     是否已经添加校验行为
        /// </summary>
        private bool _addEditBehaviored;

        /// <summary>
        ///     当前编辑时原始的值
        /// </summary>
        private object _editOldValue;

        /// <summary>
        ///     是否已经添加过显示行号行为
        /// </summary>
        private bool _showRowNumed;

        /// <summary>
        ///     校验规则集合
        /// </summary>
        private Dictionary<int, Func<int, object, bool>> _validationRules;

        /// <summary>
        ///     校验成功时需要执行的方法
        /// </summary>
        private Action<int, int> _validationSucceedAction;

        /// <summary>
        ///     初始化<see cref="DataGridViewAssistant" /> 类的新实例.
        /// </summary>
        /// <param name="dgv">DataGridView控件.</param>
        /// <exception cref="ArgumentNullException">dgv</exception>
        public DataGridViewAssistant(DataGridView dgv)
        {
            if (dgv == null)
            {
                throw new ArgumentNullException(nameof(dgv));
            }

            _dgv = dgv;

            _dgv.AutoGenerateColumns = false;
        }

        /// <summary>
        ///     添加在编辑时的校验行为.
        /// </summary>
        /// <returns>DataGridViewAssistant.</returns>
        public DataGridViewAssistant AddValidationBehavior()
        {
            if (_addEditBehaviored)
            {
                return this;
            }

            _validationRules = new Dictionary<int, Func<int, object, bool>>();

            _dgv.CellBeginEdit += DgvOnCellBeginEdit;
            _dgv.CellEndEdit   += DgvOnCellEndEdit;

            _addEditBehaviored = true;

            return this;
        }

        /// <summary>
        ///     显示行号.
        /// </summary>
        /// <returns>DataGridViewAssistant.</returns>
        public DataGridViewAssistant ShowRowNum()
        {
            if (_showRowNumed)
            {
                return this;
            }

            _dgv.RowsAdded   += (sender, args) => { ShowRowNumAction(); };
            _dgv.RowsRemoved += (sender, args) => { ShowRowNumAction(); };

            _showRowNumed = true;

            return this;
        }

        /// <summary>
        ///     添加单元格编辑校验规则.
        /// </summary>
        /// <param name="columnIndex">Index of the column.</param>
        /// <param name="ruleFunc">The rule function.</param>
        /// <returns>DataGridViewAssistant.</returns>
        public DataGridViewAssistant AddCellEditValidationRule(int columnIndex, Func<int, object, bool> ruleFunc)
        {
            if (_validationRules.ContainsKey(columnIndex))
            {
                return this;
            }

            _validationRules.Add(columnIndex, ruleFunc);

            return this;
        }

        /// <summary>
        ///     Adds the validation succeed.
        /// </summary>
        /// <param name="action">The action.</param>
        /// <returns>DataGridViewAssistant.</returns>
        public DataGridViewAssistant AddValidationSucceed(Action<int, int> action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            _validationSucceedAction = action;

            return this;
        }

        /// <summary>
        ///     单元格编辑开始时触发的事件.
        /// </summary>
        /// <param name="sender">发生源.</param>
        /// <param name="e">包含事件数据的<see cref="DataGridViewCellCancelEventArgs" />实例。</param>
        private void DgvOnCellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
        {
            // 预存旧值,进行验证失败后进行回撤.
            _editOldValue = _dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
        }

        /// <summary>
        ///     单元格编辑结束时触发的事件.
        /// </summary>
        /// <param name="sender">发生源.</param>
        /// <param name="e">包含事件数据的<see cref="DataGridViewCellEventArgs" /> 实例。</param>
        private void DgvOnCellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            if (_dgv.Columns[e.ColumnIndex].GetType().Name != typeof(DataGridViewTextBoxColumn).Name)
            {
                return; //  其他情况值都是语言设定的 不进行校验
            }

            if (_validationRules.ContainsKey(e.ColumnIndex))
            {
                if (!_validationRules[e.ColumnIndex](e.RowIndex, _dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value))
                {
                    _dgv.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = _editOldValue;

                    return;
                }
            }

            _validationSucceedAction?.Invoke(e.RowIndex, e.ColumnIndex);
        }

        /// <summary>
        ///     显示行号具体的执行方法.
        /// </summary>
        private void ShowRowNumAction()
        {
            for (var i = 0; i < _dgv.Rows.Count; i++)
            {
                _dgv.Rows[i].HeaderCell.Value = (i + 1).ToString(CultureInfo.InvariantCulture);
            }
        }
    }
}