Kevin Wienhold の回答へのコメントから外れて、ユーザーがツリービューの空のスペースをクリックして、選択したノードの選択を解除できるようにしたいだけです。
これを行うには、コントロールの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 によって選択されています (TreeView
やのような .NET 提供のコントロールListView
は単なるラッパーであることに注意してください)。 Windows API によって提供されるものと同じコントロールであり、明らかにこの "select-node-while-right-button-hold-down" 動作自体を実装しています)。
ただし、機能するのはWndProc
、派生TreeView
コントロールでオーバーライドし、WM_RBUTTONDOWN
メッセージを処理することです。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
への応答としてオーバーライドされたメソッドでコンテキスト メニューを表示し、基本クラスがメッセージを処理することを許可せずにメソッドから表示できます。これは最初のソリューションとまったく同じことを行います (右クリック イベントによってノードが選択されているように見えるのを防ぎます)。発生します。もちろん、これは、フォームの UI コードで処理されるのではなく、関連するすべてのコードがコントロールのサブクラス内に含まれている必要があることを意味します。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);
}
}
メッセージへの応答としてカスタム クラスから独自のイベントを発生させ 、フォームの UI コードから必要に応じて処理することができます。メッセージを基本コントロール クラスに渡さないことで、前の 2 つの提案と同じ目標が達成されますが、すべてのロジックをサブクラス化する代わりに、フォームの UI コードで右ボタン クリック イベントを処理できます。コントロールの.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);
}
}