题 双击后禁用扩展


有什么办法可以在doubleclick后禁用扩展TreeNode吗?

谢谢


16
2017-08-08 16:45


起源




答案:


据我所知,没有简单的方法可以实现这一目标。一种想法是拥有一个 bool 变量设置为 true 在DoubleClick事件上,并使用 e.Cancel 的财产 BeforeExpand 事件以防止节点扩展。但是,这两个事件是以相反的顺序触发的,因此这不是解决方案。我没有另外一个解决方案;如果我拿出一个会更新。

更新

我已经玩了一下这个,我找到了一种有效的方法 合理 好。正如我所提到的,问题是 BeforeExpand 发生 之前  DoubleClick,所以我们不能设置任何状态 DoubleClick 用于 BeforeExpand

但是,我们可以通过另一种方式检测(潜在)双击:通过测量两者之间的时间 MouseDown 事件。如果我们得到两个 MouseDown 定义双击的时间段内的事件(如中所述) SystemInformation.DoubleClickTime),应该是双击,对吧?而且 MouseDown 之前提出的事件 BeforeExpand。因此,以下代码运行良好:

private bool _preventExpand = false;
private DateTime _lastMouseDown = DateTime.Now;

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    e.Cancel = _preventExpand;
    _preventExpand  = false;
}

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
    int delta = (int)DateTime.Now.Subtract(_lastMouseDown).TotalMilliseconds;            
    _preventExpand = (delta < SystemInformation.DoubleClickTime);
    _lastMouseDown = DateTime.Now;
}

我说“相当不错”,因为我觉得它会阻止节点在某些情况下不应该扩展(例如,如果你在双击时间内首先点击节点文本然后点击加号)。这可能有可能以某种方式解决,或者也许你可以忍受。


13
2017-08-08 17:02



实际上,有一种非常简单的方法可以实现这一目标。 - jay_t55
@baeltazor:在发布我的答案之前,我尝试了你在答案中建议的解决方案。在你的回答下看我的评论。 - Fredrik Mörk
在MouseDown事件中,您检查点击的位置是否在最后一个MouseDown位置的X-Y方向上的几个像素(可能是3-5)内。如果是这样,并且MouseDowns在阈值范围内,则双击。 - KeithS
@KeithS:好的补充。事实上,这个距离也有一个定义: SystemInformation.DoubleClickSize。 - Fredrik Mörk
检查鼠标按下事件之间的时间和像素增量在使用时会变得过时 Clicks 的财产 MouseEventArgs 传递给了 MouseDown 事件处理程序此属性似乎是根据系统的双击配置设置的。 - Good Night Nerd Pride


private bool isDoubleClick = false;

private void treeView1_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
{
    if (isDoubleClick && e.Action == TreeViewAction.Collapse)
        e.Cancel = true;
}

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    if (isDoubleClick && e.Action == TreeViewAction.Expand)
        e.Cancel = true;
}

private void treeView1_MouseDown(object sender, MouseEventArgs e)
{
    isDoubleClick = e.Clicks > 1;
}

您可以声明私有字段isDoubleClick并如上所述设置各种TreeView事件。这将阻止双击展开/折叠TreeView节点。但是,展开/折叠将通过+和 - 图标起作用。


20
2017-09-11 09:48



你可以采用一个布尔变量,如:private bool blnDoubleClick = false;并设置如下的各种树视图事件。这将阻止双击展开/折叠树视图节点。但是,展开/折叠将通过+和 - 图标起作用。 - Suniket Patel
这应该是公认的答案,因为它不依赖于了解双击时间 - Dan
我同意这应该是例外的答案。工作完美无缺,实施起来非常简单。 - Tizz


MouseDown事件将发生在BeforeExpand / BeforeCollapse事件之前。您可以检查MouseEventArg的Clicks属性,以区分双击和单击:

bool dblClick;

private void treeView_MouseDown(object sender, MouseEventArgs e)
{
  dblClick = e.Button == MouseButtons.Left && e.Clicks == 2;
}

private void treeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
  if (e.Action == TreeViewAction.Expand) e.Cancel = dblClick;
}

3
2018-01-05 17:22





处理事件BeforeExpand并将事件args对象的属性设置为true。

private void OnBeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    e.Cancel = true;
}

TreeViewCancelEventArgs还包含受影响的节点和导致事件的操作,因此您可以实现更复杂的逻辑来启用或禁用扩展行为,而不是我的简单示例。


2
2017-08-08 17:00



嗨,不幸的是我在TreViewCancelEventArgs中看不到动作(如双击或简单扩展) - arek


是。你可以这样做。

在代码中的某处单独写下:

bool CanExpand = true;

...并在doubleclicked处理程序内写下:

CanExpand = false;

.......并且在um .. BeforeExpand事件中,输入以下内容:

if( CanExpand )
   Application.DoEvents();
else e.Cancel = true;

我希望这有帮助。


我刚试过这个,它完美无瑕。 :-)下面是我用来测试它的整个代码。所以你可以看到它是如何工作的:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        bool CanExpand = true;

        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            CanExpand = false;
        }

        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (CanExpand)
                Application.DoEvents();
            else
                e.Cancel = true;
        }
    }
}

2
2017-08-11 05:09



我刚试了这个,它显示了一个 非常 不一致的行为(它允许第一次展开doubleclick,因为 BeforeExpand 之前被提出来了 DoubleClick,然后它阻止下一次扩展尝试,无论它是如何被触发的)。此外,您的代码可能应该设置 CanExpand = true 最后的 BeforeExpand 事件处理程序,或者它将阻止所有未来的扩展尝试。 - Fredrik Mörk


我知道这个线程已经很老了,但现在遇到了同样的问题并找到了替代解决方案。我不确定 treeView_blockInfo_NodeMouseDoubleClick 在这个线程被打开时可用,但我的解决方案是附加此事件并使用这段代码:

private void treeView_blockInfo_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
    if (!e.Node.IsExpanded)
    {
        e.Node.Expand();
    }
    else
    {
        e.Node.Collapse();
    }
}

适合我(虽然我没有深入测试这个)。我能想到的唯一问题是它可能会导致闪烁。


1
2017-12-26 13:48





这是一个简单的解决方案:

int treeX;   // somewhere in class scope

// Add a MouseMove event handler
private void treeView1_MouseMove(object sender, MouseEventArgs e)
{
    treeX = e.X;
}

// Add a BeforeExpand event handler
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    if (treeX > e.Node.Bounds.Left) e.Cancel = true;
}

0
2017-10-21 19:16



我担心,这会阻止每次鼠标在节点上的扩展(实际上,因为你只是检查x坐标,当鼠标移过任何其他节点时,它也可能发生......)。根据问题,只有在双击的情况下才能防止扩展。 - MartinStettner


最简单的方法:

treeList.OptionsBehavior.AllowExpandOnDblClick = false;

-2
2018-05-22 15:34



此解决方案不适用于Winforms树形图。我认为 这个 控制是这个答案的作者使用的。 - transistor1