有时,向上键在 DataGridView 上不起作用
本文关键字:DataGridView 不起作用 有时 | 更新日期: 2023-09-27 18:35:08
有时向上键不起作用DataGridView
.
我不知道为什么,尤其是这很奇怪,因为没有为DataGridView
键的事件分配代码......
选择模式为全行选择
多选为假
这段代码没有帮助...
private void dataGridView1_PreviewKeyDown(object sender, reviewKeyDownEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Down:
e.IsInputKey = true;
break;
case Keys.Up:
e.IsInputKey = true;
break;
}
}
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Down)
{
e.Handled = true;
}
else if (e.KeyData == Keys.Up)
{
e.Handled = true;
}
}
有什么线索吗?
附言
似乎SelectionChanged
方法做了一些艰苦的工作......所以当我禁用它时,一切都很好。
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
// Some hard work
}
所以问题是如何优化它。
我假设使用计时器,所以当用户停止选择箭头键 1 秒后应执行SelectionChanged
方法的代码。
关于最佳方法的任何线索?
在执行SelectionChanged
的过程中,网格不知何故失去了焦点。这可能是因为动态创建和插入用户控件而发生的。
所以我做了三个调整,现在很好!
bool canDoHardWork = true;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (canDoHardWork)
{
int interval = 2000; // Just 2 seconds
Task.Factory.StartNew(() =>
{
canDoHardWork= false;
Thread.Sleep(interval);
this.BeginInvoke((Action)(() =>
{
PopulateTabs(); // Very hard work
dataGridView1.Focus();
canDoHardWork= true;
}), null);
});
}
}
请注意,当您PopulateTabs()
时,您必须再次将焦点设置回DataGridView
。这是您在向上和向下箭头键方面的问题。自定义控件捕获了键的事件。至于非常艰苦的工作(PopulateTabs),我注意到您正在使用异步线程与TPL
。你有没有想过取消睡眠间隔,因为它似乎是多余的,只需设置你的 DoesHardWork 变量并将焦点更改为任务之外的DataGridView
。它目前的工作方式的原因是,SelectionChanged
事件在第一次"DoesHardWork"第二次失败时触发两次,因为 DoesHardWork 在处理PopulateTabs()
时仍然是假的。一个更优雅的解决方案是将PopulateTabs()
生成的 CellValue/RowValue/Control 设置为您将使用 IAsyncResult
从 PopulateTabs() 返回的对象。
像这样:
bool canDoHardWork = true;
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (canDoHardWork)
{
IAsyncResult result;
Task.Factory.StartNew(() =>
{
canDoHardWork = false;
result = this.BeginInvoke((Func<Button>)(() =>
{
canDoHardWork = true;
return PopulateTabs(); // Very hard work
}), null);
this.dataGridView1.Controls.Add((Button)this.EndInvoke(result));
dataGridView1.Focus();
});
}
}
无需等待线程完成,因为它只会将自定义控件添加到 DataGridView 并将控件返回到主线程。示例中的线程睡眠将发生在异步线程上,因此是冗余的。在此示例中,繁重的工作是在另一个线程上执行的,使主线程可以继续接受输入。必须在添加控件后放置 DataGridView 的焦点,否则焦点将在需要时不会更改。
也许晚了,但在我的问题中,使用e.Handled = true
是问题所在。明智地放置命令的位置。
例:如果在事件 Key Down 上,并且每个 Key Enter 该用户按您希望所选行不向下移动,并且您使用事件e.Handled
。像这样放置该命令:
if (e.KeyCode == Keys.Enter)
{
e.Handled = true;
//Do the command
}
不要在 if 条件之外使用,因为它会冻结所选行,无论用户按什么键。
在您的情况下,在向上和向下按键事件中使用e.Handled
只会使情况变得最糟糕,因为每次用户按下键时,所选行都不会向上或向下移动,因为使用命令e.Handled
,您命令程序不要将光标从所选行移动。
对不起,我的英语不好...