C# 有时上下键在DataGridView上不起作用
有时键向上向下在C# 有时上下键在DataGridView上不起作用,c#,winforms,datagridview,C#,Winforms,Datagridview,有时键向上向下在DataGridView上不起作用 我不知道为什么,尤其是它很奇怪,因为没有为key的DataGridView事件分配代码 SelectionMode为FullRowSelect 多重选择是错误的 此代码没有帮助 private void dataGridView1_PreviewKeyDown(object sender, reviewKeyDownEventArgs e) { switch (e.KeyCode
DataGridView
上不起作用
我不知道为什么,尤其是它很奇怪,因为没有为key的DataGridView
事件分配代码
SelectionMode为FullRowSelect
多重选择是错误的
此代码没有帮助
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()时仍然为false。更优雅的解决方案是将由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();
});
}
}
boolcandohardwork=true;
private void dataGridView1\u SelectionChanged(对象发送方,事件参数e)
{
if(烛台硬件)
{
IAsyncResult结果;
Task.Factory.StartNew(()=>
{
坎多哈德=假;
结果=此.BeginInvoke((Func)(()=>
{
坎多哈德=真;
return PopulateTabs();//非常辛苦的工作
}),空);
this.dataGridView1.Controls.Add((按钮)this.EndInvoke(结果));
dataGridView1.Focus();
});
}
}
无需等待线程完成,因为它只需将自定义控件添加到DataGridView并将控件返回主线程。示例中的线程睡眠将发生在异步线程上,因此是冗余的。在本例中,在另一个线程上执行重载,使主线程可以继续接受输入。必须在添加控件后为DataGridView设置焦点,否则焦点在需要时不会改变 使用PreviewKeyUp/PreviewKeyDown事件。@MitraM是否介意解释为什么必须使用它们以及如何使用它们?请参阅和。@MitraM抱歉,您的代码没有帮助。我刚刚更新了我的答案。请复习。你的评论对我来说太棒了。您是否介意在中添加一个代码示例,以便我可以对其进行测试,并可能将您的答案标记为正确答案?