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);
}
}
}
}