DOBON.NET DOBON.NETプログラミング掲示板過去ログ

コンテキストメニューをボタンの下に表示したい

環境/言語:[VB2008]
分類:[.NET]

こんにちは。

ボタンを押したら、プルダウンメニューのように
そのボタンの下にContextMenuStripを表示させたくて
次のコードを書きましたが、位置が正しくなりません。

        ContextMenuStrip1.Show()
        ContextMenuStrip1.Top = Button1.Bottom
        ContextMenuStrip1.Left = Button1.Left

こちらを書くと比較的いい感じの位置なのですが
        ContextMenuStrip1.Show()
        ContextMenuStrip1.Top = MousePosition.Y
        ContextMenuStrip1.Left = MousePosition.X

出したいのは、マウス位置ではなく、ボタンの下端なのです。

DesktopLocationを指定するようですが、
その指定方法がわかりません。

やり方をご存じでしたら教えてください。

よろしくお願いします。
■No23825に返信(FutoNekoさんの記事)
> 出したいのは、マウス位置ではなく、ボタンの下端なのです。

こうかな?

ContextMenuStrip1.Show()
Dim p As Point = Me.PointToScreen(New Point(Button1.Left, Button1.Bottom))
ContextMenuStrip1.Top = p.Y
ContextMenuStrip1.Left = p.X

ただし、メニューは画面内に収まるように表示されるため、
ボタンの位置が、画面端からはみ出るような場所にあった場合や、
マルチモニタ環境で複数のモニタに跨るような位置にあった場合は、
表示位置がずれます。
■No23827に追伸(魔界の仮面弁士の記事)
> Dim p As Point = Me.PointToScreen(New Point(Button1.Left, Button1.Bottom))

上記訂正:

Dim p As Point = Button1.Parent.PointToScreen(New Point(Button1.Left, Button1.Bottom))
ToolStripのSplitButtonをButtonの後ろに隠して似たようなことをやったことがあります・・・。
ありがとうございます。

下記の二つのやり方で、どちらも
同じ動作になりました。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    ContextMenuStrip1.Show()
    Dim p As Point = Button1.Parent.PointToScreen(New Point(Button1.Left, Button1.Bottom))
    ContextMenuStrip1.Top = p.Y
    ContextMenuStrip1.Left = p.X
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    Dim p As Point = Button2.Parent.PointToScreen(New Point(Button2.Left, Button2.Bottom))
    ContextMenuStrip2.Show(p.X, p.Y)
End Sub
解決済み!
■No23832に返信(FutoNekoさんの記事)
> 下記の二つのやり方で、どちらも
> 同じ動作になりました。

Button2 の実装であれば、最初からボタンの下に配置されますね。

Button1 の実装の場合、まず初期位置(例:画面左上)に表示されて、
そこから一瞬遅れて Button1 の下に表示されなおすという動作になるので、
実行環境によっては、その遅れが目立ってしまうかも知れません。
(一瞬すぎて気にならない程度な環境もありますが)
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板