C# 当.NET treeview的click事件中存在长逻辑时,双击被忽略

C# 当.NET treeview的click事件中存在长逻辑时,双击被忽略,c#,treeview,double-click,C#,Treeview,Double Click,在.net树视图中捕获双击事件时遇到问题。在click事件中,我有一些耗时的逻辑(例如,一个数据库调用来更新UI的一部分)。因此,由于此处的时间延迟,双击时的第二次单击被忽略,因此,树视图预期的正常行为(即双击时展开)不起作用。 我的点击事件如下 private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { if (e.Button == MouseButtons.Left) { //

在.net树视图中捕获双击事件时遇到问题。在click事件中,我有一些耗时的逻辑(例如,一个数据库调用来更新UI的一部分)。因此,由于此处的时间延迟,双击时的第二次单击被忽略,因此,树视图预期的正常行为(即双击时展开)不起作用。 我的点击事件如下

private void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
{ 
 if (e.Button == MouseButtons.Left)
{
//database call
}
}
当系统双击时间设置为最快时,数据库调用可防止触发双击。 我试图在中实现一个线程,但我的应用程序阻止我使用其中的任何其他线程。因此,请建议一种无需使用线程即可触发双击事件(或让节点在双击时展开)的方法:(


提前感谢:)

那么,理想情况下,数据库调用应该在另一个线程中进行。你应该考虑重构你的应用程序,使之成为可能。


一个可能的解决方法是在
treeView\u NodeMouseClick
中处理右键单击(或中键单击),这样
treeView\u nodemouseboolclick
仍然需要左键双击。

我怀疑您是否可以在没有其他线程的情况下完成这项工作。在您的案例中发生的是,DB调用(可能是资源密集型的)发生在事件处理程序中,事件处理程序由事件调度程序线程执行,该线程是负责GUI的代码(包括对事件的响应,而不仅仅是渲染)

理想的解决方案是使用后台工作人员,让其完成繁重的工作。如果您需要执行一些GUI操作,那么可以查看前面的SO线程以获取更多信息


也就是说,如果你真的不能使用线程,你可以做的就是在DB操作之前禁用你的控件,然后再重新启用它。这应该不允许用户通过该控件向您发送新事件,但也就是说,应用程序很可能会在一段时间内没有响应。

不要在主线程中执行任何耗时超过几毫秒的工作,它已经有很多工作要做了。让它来吧

你可以利用这里


提供了许多重载,要知道为什么我选择了一个带有这么多参数的重载,您可以,这也同样适用。

这是什么意思:
但是我的应用程序阻止我使用其中的任何其他线程
?我不能使用其他线程。它给出了一个线程冲突异常,因为应用程序的其余部分是以这种方式创建的。如果可能,请建议一种无螺纹的方法:(您使用的是.net的哪个版本?.net版本4。如果双击,您仍然希望DB代码也运行吗?一个简单的解决方案是在单击事件中启动一个计时器,当计时器过期时,它将运行DB代码,并且您仍然可以按照其他人的建议在单独的线程中执行DB代码。如果您不想这样做双击时运行DB代码,您可以取消双击事件中的计时器。对于RMB,我只想显示上下文菜单,因此不应为此发送数据库调用。典型行为是LM click-使用DB调用更新UI;LM双击-使用DB调用更新UI,并展开treeview;RMB-显示上下文菜单而不使用upd感谢您的建议。我会尝试将其输入到我的代码中,然后查看:)
var uiContext = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task.Factory.StartNew(() =>
{
    //Your database call here, which will be run in threadpool thread
    return resultFromDatabase;
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
task.ContinueWith(antecedent =>
{
    var resultFromDatabase = antecedent.Result;//This runs in main thread
    //Update UI
}, CancellationToken.None, TaskContinuationOptions.None, uiContext);