Отключить расширение после двойного щелчка - PullRequest
16 голосов
/ 08 августа 2009

Можно ли как-то отключить расширение TreeNode после двойного щелчка ??

Спасибо

Ответы [ 9 ]

22 голосов
/ 11 сентября 2012
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 при двойном щелчке. Однако развернуть / свернуть будет работать с помощью значков + и -.

13 голосов
/ 08 августа 2009

Насколько я знаю, простого способа добиться этого не существует. Можно подумать, что в событии DoubleClick переменная bool установлена ​​в true, а свойство 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;
}

Я говорю «довольно хорошо», потому что я чувствую, что в некоторых случаях он не позволяет расширяться узлу, когда этого делать не следует (например, если вы в течение времени двойного щелчка нажимаете сначала на текст узла, а затем на знак плюс). Это можно было бы решить каким-то образом, или, возможно, вы можете жить с этим.

3 голосов
/ 05 января 2015

Событие MouseDown будет происходить до событий BeforeExpand / BeforeCollapse. Вы можете проверить свойство Clicks MouseEventArg, чтобы различать двойной щелчок и один щелчок:

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;
}
2 голосов
/ 11 августа 2009

Да. Вы можете сделать это.

Где-то само по себе в коде напишите это:

bool CanExpand = true;

... и внутри обработчика двойного щелчка напишите:

CanExpand = false;

....... и внутри ит ... события 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 голосов
/ 08 августа 2009

Обрабатывает событие BeforeExpand и присваивает свойству Cancel объекта args события значение true.

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

TreeViewCancelEventArgs содержит также уязвимый узел и действие, вызвавшее событие, поэтому вы можете реализовать более сложную логику для включения или отключения поведения расширения, чем в моем простом примере.

1 голос
/ 26 декабря 2013

Я знаю, что эта ветка довольно старая, но теперь имела ту же проблему и нашла альтернативное решение. Я не уверен, был ли treeView_blockInfo_NodeMouseDoubleClick доступным во время открытия этой темы, но я решил присоединить это событие и использовать этот фрагмент кода:

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

У меня работает (хотя я не проверял это до глубины). Единственная проблема, о которой я могу думать, это то, что она может вызвать мерцание.

0 голосов
/ 30 января 2019

Попробуйте изменить точку зрения. Вместо того, чтобы отключить расширение при двойном щелчке, вы можете разрешить расширение только тогда, когда пользователь нажимает кнопку [+].

Таким образом, вы можете использовать метод GetHitTestInfoAt и разрешить расширение, только если выбранным элементом является htOnButton. Следующий код работает для Delphi 6:

procedure Form1.TreeView1Expanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean);
var
   p:Tpoint;
   ht:THitTests;
begin
p:=Mouse.CursorPos;
ht:=treeview1.GetHitTestInfoAt(treeview1.ScreenToClient(p).x,treeview1.screentoclient(p).y);
AllowExpansion:=(htOnButton in ht);
end;
0 голосов
/ 22 мая 2014

Самый простой способ:

treeList.OptionsBehavior.AllowExpandOnDblClick = false;
0 голосов
/ 21 октября 2012

Вот простое решение:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...