Можно ли отключить расширение TreeNode после doubleclick?
Спасибо
Можно ли отключить расширение TreeNode после doubleclick?
Спасибо
Нет простого способа достичь этого, насколько я знаю. Одна мысль заключалась бы в том, чтобы переменная bool
была установлена в true
в событии DoubleClick и использовала свойство e.Cancel
события BeforeExpand
, чтобы предотвратить расширение node. Однако эти два события запускаются в обратном порядке, так что это не решение. У меня нет другого решения с моей головы; будет обновляться, если я придумаю один.
Обновление
Я немного поиграл с этим, и я нашел один способ, который работает достаточно хорошо. Как я уже упоминал, проблема заключается в том, что 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;
}
Я говорю "довольно хорошо", потому что я чувствую, что он предотвращает расширение node в некоторых случаях, когда это не должно (например, если вы в течение двойного щелчка нажимаете сначала на текст node, а затем на плюс знак). Это можно было бы решить каким-то образом, или, возможно, вы с этим справитесь.
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 при двойном щелчке. Однако развернуть/свернуть будет работать с помощью значков + и -.
Событие 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;
}
Обрабатывает событие BeforeExpand и устанавливает свойство Отменить событие args object к true.
private void OnBeforeExpand(object sender, TreeViewCancelEventArgs e)
{
e.Cancel = true;
}
TreeViewCancelEventArgs содержит также затронутый node и действие, вызвавшее событие, чтобы вы могли реализовать более сложную логику, чтобы включить или отключить поведение расширения, чем мой простой пример.
Да. Вы можете сделать это.
Где-то сам по себе в коде напишите это:
bool CanExpand = true;
... и внутри обработчика с двойным щелчком напишите это:
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;
}
}
}
Я знаю, что эта ветка довольно старая, но теперь такая же проблема и нашла альтернативное решение. Я не уверен, что treeView_blockInfo_NodeMouseDoubleClick
был доступен в то время, когда этот поток был открыт, но мое решение состоит в том, чтобы прикрепить это событие и использовать этот фрагмент кода:
private void treeView_blockInfo_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
if (!e.Node.IsExpanded)
{
e.Node.Expand();
}
else
{
e.Node.Collapse();
}
}
Работает для меня (хотя я не тестировал это на глубину). Единственная проблема, о которой я могу думать, это то, что она может вызвать мерцание.
Здесь простое решение:
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;
}
Попробуйте изменить точку зрения. Вместо того, чтобы отключить расширение при двойном щелчке, вы можете разрешить расширение только тогда, когда пользователь нажимает кнопку [+].
Таким образом, вы можете использовать метод 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;
Простейший способ:
treeList.OptionsBehavior.AllowExpandOnDblClick = false;