Выйдя из вашего комментария к ответу Кевина Винхолда, вы просто хотите разрешить пользователю щелкнуть пустое пространство в древовидной структуре и отменить выбор любого выбранного узла.
Это можно сделать, обработав MouseDown
событие элемента управления TreeView
и установка SelectedNode
свойство на null
, если мышь была нажата над местом, которое не содержит узла. Например, вы можете использовать следующий код:
private void myTreeView_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (myTreeView.HitTest(e.Location).Node == null)
{
myTreeView.SelectedNode = null;
}
}
При этом используется HitTest
метод, чтобы определить, какой узел расположен в конкретную точку, указав местоположение события мыши как точку для проверки. Вам не нужен другой код для выбора узлов, как обычно, когда пользователь делает щелчок по ним; это обрабатывается автоматически TreeView
.
РЕДАКТИРОВАТЬ: Как видно из моего комментария к вопросу, мне все еще крайне неясно, чего вы здесь пытаетесь достичь. Если вы действительно заинтересованы в предотвращении временного выделения узла, когда вы удерживаете правую кнопку мыши в пустом пространстве сбоку от узла, все становится немного сложнее.
Я рассматривал эту проблему раньше, и сложность заключается в том, что сообщения окна не принимаются, пока кнопка мыши удерживается нажатой, по крайней мере, до тех пор, пока мышь не будет перемещена (в этом случае узел все равно больше не выбирается) . Такое поведение, очевидно, продиктовано операционной системой, и его нелегко переопределить с помощью стандартных событий, предоставляемых .NET. Вы можете попытаться отменить щелчок правой кнопки в событии MouseDown
в течение всего дня, но узел выбирается Windows до того, как это событие когда-либо возникнет в вашем элементе управления (помните, что предоставляемые .NET элементы управления, такие как TreeView
и ListView
, являются просто обертки вокруг тех же элементов управления, предоставляемых Windows API, который, по-видимому, сам реализует это поведение «select-node-while-right-button-hold-down»).
Однако то, что работает, переопределяет _ 11_ в производном TreeView
элементе управления и обработка _ 13_ сообщение. Но обратите внимание, что даже установка свойства SelectedNode
на null
здесь не работает, потому что это не обрабатывается до тех пор, пока после Windows автоматически не выберет узел в ответ на щелчок правой кнопкой мыши - независимо от того, что вы делаете. , вы должны запретить базовому TreeView
элементу управления получать WM_RBUTTONDOWN
сообщение. Итак, у вас есть несколько вариантов, как с этим справиться:
Вы можете просто отменить сообщение, появляющееся при щелчке правой кнопкой мыши, преждевременно выполнив экстренное спасение с помощью оператора return
. Конечно, это означает, что вы не сможете обработать это событие в своем MouseDown
обработчике, потому что на самом деле оно никогда не передается в элемент управления! Так что, если вы хотите показать всплывающее контекстное меню, это, вероятно, не сработает для вас.
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
return;
}
base.WndProc(ref m);
}
}
Вы можете отобразить свое контекстное меню в переопределенном методе WndProc
как ответ на сообщение WM_RBUTTONDOWN
, а затем return
из метода, не позволяя базовому классу обрабатывать сообщение. Это делает то же самое, что и первое решение (предотвращает то, что событие щелчка правой кнопкой мыши вызывает выделение узла), но позволяет отображать контекстное меню (или делать что-либо еще, что вы хотите) всякий раз, когда щелчок правой кнопкой мыши имеет место. Конечно, это означает, что весь соответствующий код должен содержаться в вашем подклассе элемента управления TreeView
, а не обрабатываться в коде пользовательского интерфейса вашей формы, что может или не может быть удобно для вас.
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
//Create and show a context menu
var myContextMenu = new ContextMenuStrip();
myContextMenu.Items.Add("First Item");
myContextMenu.Items.Add("Second Item");
return;
}
base.WndProc(ref m);
}
}
Вы можете инициировать свое собственное RightMouseClick
событие из ваш собственный TreeView
класс в качестве ответа на сообщение WM_RBUTTONDOWN
, которое вы затем можете обрабатывать по своему усмотрению из кода пользовательского интерфейса вашей формы. Не передавая сообщение WM_RBUTTONDOWN
базовому классу управления TreeView
, это позволяет достичь той же цели, что и предыдущие два предложения, но позволяет обрабатывать событие щелчка правой кнопкой мыши в коде пользовательского интерфейса вашей формы вместо того, чтобы помещать всю свою логику в WndProc
подкласса элемента управления.
public class NewTreeView : System.Windows.Forms.TreeView
{
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_RBUTTONDOWN = 0x204;
if (m.Msg == WM_RBUTTONDOWN)
{
//Raise your custom event
OnRightMouseClick(new EventArgs());
return;
}
base.WndProc(ref m);
}
}
person
Cody Gray
schedule
02.12.2010