为了实现“在单元格输入数据后,点击任意位置完成输入并触发验证”,可以通过以下步骤修改代码:
解决方案
在窗体或容器控件中捕获鼠标点击事件,强制提交 DataGridView 的当前编辑。以下是完整实现:
csharp
复制
// 在窗体构造函数或加载事件中订阅 MouseDown 事件
public Form1()
{
InitializeComponent();
this.MouseDown += Form1_MouseDown;
dataGridView1.MouseDown += DataGridView1_MouseDown;
}
// 点击窗体任意位置时提交编辑(DataGridView 外部)
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.EndEdit(DataGridViewDataErrorContexts.Commit);
}
}
// 点击 DataGridView 内部时提交编辑(处理内部点击)
private void DataGridView1_MouseDown(object sender, MouseEventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
dataGridView1.EndEdit(DataGridViewDataErrorContexts.Commit);
}
}
// 原有的 CellValidating 验证逻辑(保持不变)
private void DataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.RowIndex < 0) return;
var row = dataGridView1.Rows[e.RowIndex];
var config = row.DataBoundItem as TestConfig;
if (e.ColumnIndex == dataGridView1.Columns["Setting"].Index)
{
if (!ValidateSetting(config.Mode, e.FormattedValue.ToString()))
{
row.ErrorText = "无效的设置值";
e.Cancel = true;
}
}
if (e.ColumnIndex == dataGridView1.Columns["Delay"].Index)
{
if (!double.TryParse(e.FormattedValue.ToString(), out _))
{
row.ErrorText = "必须输入有效数字";
e.Cancel = true;
}
}
}
________________________________________
关键代码解释
1. Form1_MouseDown 和 DataGridView1_MouseDown 方法
o 当用户在 窗体任意位置 或 DataGridView 内部 点击鼠标时,触发这两个事件。
o 检查 dataGridView1.IsCurrentCellDirty:判断当前是否有单元格处于编辑状态且存在未提交的更改。
o 调用 dataGridView1.EndEdit(DataGridViewDataErrorContexts.Commit):强制提交编辑,触发 CellValidating 事件进行验证。
2. DataGridViewDataErrorContexts.Commit 参数
o 明确告知 DataGridView 提交操作的上下文,确保验证逻辑正确执行。
3. 与原有 CellValidating 逻辑的配合
o 提交编辑后,自动触发 CellValidating 事件,执行数据验证。
o 若验证失败(如输入无效),通过 e.Cancel = true 阻止输入生效,并显示错误提示。
________________________________________
效果演示
操作步骤 行为
1. 编辑单元格 用户点击单元格并输入内容(如修改 "Delay" 列的值)。
2. 点击任意位置 鼠标点击窗体其他区域、按钮或其他控件。
3. 自动提交并验证 DataGridView 提交编辑,触发 CellValidating 事件验证输入。
4. 验证结果反馈 若输入无效,显示错误提示并阻止焦点离开;若有效,更新数据并清除错误提示。
________________________________________
注意事项
1. 避免与内部控件冲突
o 如果窗体上有其他需要处理点击事件的控件(如按钮),此代码不会干扰其正常逻辑,因为提交操作发生在控件点击事件之前。
2. 焦点管理
o 若验证失败(e.Cancel = true),焦点会保留在原单元格,直到用户输入有效值。
3. 性能优化
o 仅在存在未提交更改时调用 EndEdit,避免不必要的操作。
4. 错误提示清除
o 在 CellValidated 事件中清除错误提示,确保界面清洁:
csharp
复制
private void DataGridView1_CellValidated(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.Rows[e.RowIndex].ErrorText = "";
}
________________________________________
完整流程图
mermaid
复制
sequenceDiagram
participant User
participant Form
participant DataGridView
participant CellValidating
User->>DataGridView: 编辑单元格
User->>Form: 点击任意位置
Form->>DataGridView: 检查 IsCurrentCellDirty
alt 存在未提交更改
DataGridView->>DataGridView: 调用 EndEdit
DataGridView->>CellValidating: 触发验证
alt 验证通过
CellValidating-->>DataGridView: 更新数据
else 验证失败
CellValidating-->>DataGridView: 显示错误,阻止提交
end
end
________________________________________
通过此方案,用户无需按 <kbd>Enter</kbd> 键即可通过点击任意位置提交输入并触发验证逻辑,提升操作流畅度。