2009-08-08 8 views

Odpowiedz

13

Nie ma prostego sposobu na osiągnięcie tego, o ile wiem. Jedną z nich byłoby ustawienie zmiennej bool na true w zdarzeniu DoubleClick i użycie właściwości e.Cancel zdarzenia BeforeExpand, aby zapobiec rozszerzeniu węzła. Te dwa zdarzenia są jednak uruchamiane w odwrotnej kolejności, więc nie jest to rozwiązanie. Nie mam innego rozwiązania z mojej głowy; zaktualizuje, jeśli wymyślę jedną.

Aktualizacja

Grałem około z tym trochę i znalazłem jeden sposób, który działa rozsądnie dobrze. Jak wspomniałem, problem polega na tym, że BeforeExpand dzieje się przedDoubleClick, więc nie możemy ustawić żadnego stanu w DoubleClick do użycia w BeforeExpand.

Możemy jednak wykryć (potencjalne) podwójne kliknięcia w inny sposób: mierząc czas między wydarzeniami MouseDown. Jeśli otrzymamy dwa zdarzenia z okresu MouseDown w okresie, który definiuje podwójne kliknięcie (jak podano w SystemInformation.DoubleClickTime), powinno to być podwójne kliknięcie, prawda? A wydarzenie MouseDown jest zgłaszane przed BeforeExpand. Tak, poniższy kod działa dość dobrze:

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; 
} 

mówię „raczej dobrze”, bo czuję, że zapobiega węzeł od rozszerzenia w niektórych przypadkach, kiedy nie powinien (na przykład, jeśli w podwójne kliknięcie czas kliknięcia najpierw na tekście węzła, a następnie na znaku plus). To może być możliwe do rozwiązania w jakiś sposób, lub może z tym żyć.

+1

Faktycznie, nie jest bardzo prostym sposobem na osiągnięcie tego. –

+1

@baeltazor: Wypróbowałem rozwiązanie, które zaproponowałeś w swojej odpowiedzi przed opublikowaniem mojej odpowiedzi. Zobacz moje komentarze pod twoją odpowiedzią. –

+1

To całkiem ciekawe rozwiązanie, ale działa :) Dzięki :) – arek

2

Uchwyty zdarzenie BeforeExpand i ustawić właściwość Cancel args zdarzenia z obiektu na true.

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

W TreeViewCancelEventArgs zawiera również danego węzła i działania, który spowodował zdarzenie tak można wdrożyć bardziej wyrafinowane logiki aby włączyć lub wyłączyć zachowanie rozszerzenia niż mój prosty przykład.

+0

Hi Niestety Nie znam zobaczyć działanie (jak DoubleClick lub prosty rozwiń) w TreViewCancelEventArgs – arek

2

Tak. Możesz to zrobić.

Gdzieś sama w kodzie napisać to:

bool CanExpand = true; 

... i wewnątrz doubleclicked obsługi napisać to:

CanExpand = false; 

....... i wewnątrz um. - Zdarzenie BeforeExpand, wpisz:

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

Mam nadzieję, że to pomogło.


Właśnie to przetestowałem i działa bezbłędnie. :-) Poniżej znajduje się cały kod, który użyłem do przetestowania go.Więc można zobaczyć, jak to działa:


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; 
     } 
    } 
} 
+1

Właśnie wypróbowałem to i to pokazuje * bardzo * niespójne zachowanie (pozwala na pierwsze rozwinięcie w podwójnym kliknięciu, ponieważ 'BeforeExpand' jest podnoszone przed' DoubleClick', wtedy blokuje następną próbę rozwinięcia, niezależnie od tego, jak jest wyzwalana) . Ponadto twój kod powinien prawdopodobnie ustawić "CanExpand = true" na końcu w procedurze obsługi zdarzeń "BeforeExpand" lub zablokuje wszystkie przyszłe próby rozszerzenia. –

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

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

private void treeView1_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (e.Clicks > 1) 
     blnDoubleClick = true; 
    else 
     blnDoubleClick = false; 
} 

Można wziąć logiczną zmienną takiego: private bool blnDoubleClick = false; i ustaw różne zdarzenia widoku drzewa w następujący sposób. Zapobiegnie to rozwinięciu/zwijaniu węzła drzewa widoku przy dwukrotnym kliknięciu. Jednak rozwiń/zwiń będzie działał za pośrednictwem ikon + i -.

+1

Można użyć zmiennej boolowskiej, takiej jak: private bool blnDoubleClick = false; i ustaw różne zdarzenia związane z widokiem drzewa w następujący sposób. Zapobiegnie to rozwinięciu/zwijaniu węzła drzewa widoku przy dwukrotnym kliknięciu. Jednak rozwijanie/zwijanie będzie działało poprzez + i - ikony. –

+1

To powinno być zaakceptowaną odpowiedzią, ponieważ nie polega na znajomości taktów podwójnego kliknięcia. – Dan

+0

Zgadzam się, że to powinna być jedyna odpowiedź. Pracował bez zarzutu i super prosty w realizacji. – Tizz

0

Oto proste rozwiązanie:

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

Obawiam się, że uniemożliwiłoby to rozszerzenie za każdym razem, gdy mysz znajduje się nad węzłem (w rzeczywistości, ponieważ sprawdzasz tylko współrzędną x, może się to również zdarzyć, gdy mysz znajdzie się nad jakimkolwiek innym węzłem ...). W przypadku dwukrotnego kliknięcia zgodnie z pytaniem można zapobiec rozszerzeniu. – MartinStettner

1

Znam ten wątek jest dość stary, ale miał ten sam problem teraz i znaleźć alternatywne rozwiązania. Nie jestem pewien, czy treeView_blockInfo_NodeMouseDoubleClick był dostępny w tym czasie ten wątek został otwarty, ale moje rozwiązanie jest dołączenie tego zdarzenia i wykorzystać ten kawałek kodu:

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

pracuje dla mnie (choć nie zostało to do testowania głębokość). Jedyny problem, jaki mogę sobie wyobrazić, to to, że może powodować migotanie.

-2

Najprostszy sposób:

treeList.OptionsBehavior.AllowExpandOnDblClick = false; 
+0

To rozwiązanie nie ma zastosowania do treelisty WinForm. Myślę, że kontrola ta (https://documentation.devexpress.com/#windowsforms/DevExpressXtraTreeListTreeList_OptionsBehaviortopic) jest tym, czego użył autor tej odpowiedzi. – transistor1

3

zdarzenie A MouseDown nastąpi przed wydarzeniami BeforeExpand/BeforeCollapse. Można sprawdzić właściwość kliknięć MouseEventArg odróżnić DoubleClick i jednym kliknięciem:

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; 
}