- PR -

DataGridViewスクロールバーのContextMenu

投稿者投稿内容
ポンタ
会議室デビュー日: 2007/06/13
投稿数: 10
投稿日時: 2008-02-27 08:44
.Net Framework 2.0 C#で開発しているのですが、DataGridViewのスクロールバーを右クリックすると、ContextMenuが表示されてしまいます。
右クリックをしてもContextMenuを表示しないようにする方法がありましたら、教えていただけないでしょうか。

宜しくお願いします。
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2008-02-27 10:35
そもそもスクロールバー自体に規定の動きを変更する口が無いので、
DataGridViewが包含しているスクロールバーなら、なおさらですよね。
(DataGridViewからスクロールバーを取得することはできますが。。)

個人的には、スクロールバー上で右クリックすることは少ないと思いますし、
あえて右クリックするということは、メニューを使いたいときかなと。
(つまり、表示されてもいいじゃないか、、と。)

この辺りは作りたいモノによって違うでしょうから、一概に言えないとは思いますが、、、。
くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-02-27 11:02
ContextMenuがNull(Nothing)の場合、規定のメニューが呼ばれるようなので
簡単な例としてですが・・・下記の様にすることで、非表示が出来るかと。

DataGridViewの垂直スクロールバーのContextMenuに設定。(Page_Load等で)
コード:

Dim scrlbar As VScrollBar = Me.DataGridView.Controls(1)
scrlbar.ContextMenu = New ContextMenu '' 項目の無いContextMenu



水平スクロールバーはControls(0)でHScrollBarとして取得できます。
ただ、DataGridView.Controlsでコントロール取得の際は
Findや型チェックを行った方が安全かと思われ。

[修正]
ContextMenuを継承したカスタムContextMenuを設定するよう記述しましたが
Itemが空のContextMenuを設定するだけで実現できるので、コード修正しました。

[ メッセージ編集済み 編集者: くまっち 編集日時 2008-02-27 11:09 ]
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2008-02-27 11:23
引用:

くまっちさんの書き込み (2008-02-27 11:02) より:

[修正]
ContextMenuを継承したカスタムContextMenuを設定するよう記述しましたが
Itemが空のContextMenuを設定するだけで実現できるので、コード修正しました。



!!
試してみたら出来ました。
素晴らしいっす。

コード:
BindingFlags bf = BindingFlags.NonPublic |
                  BindingFlags.GetField  | BindingFlags.Instance;

Type type = this.dataGridView1.GetType();

HScrollBar hScrollBar = (HScrollBar)type.InvokeMember
    ("horizScrollBar", bf, null, this.dataGridView1, null);

hScrollBar.ContextMenu = new ContextMenu();
 



と強引に取ってみたけど、DataGridViewのControlsから探すのがいいですね。
ポンタ
会議室デビュー日: 2007/06/13
投稿数: 10
投稿日時: 2008-02-27 14:12
みなさん、ありがとうございます。

Controlsから取得してみます。
ポンタ
会議室デビュー日: 2007/06/13
投稿数: 10
投稿日時: 2008-02-27 15:42
ControlsからVScrollBarを取得してContextMenuをNewしたら、右クリックで表示されなくなりました。

でも、右クリックのまま、ドラッグ&ドロップすると、ショートカットが表示されてしまいます。
TextBoxとかでは、ShortCutsEnableをFalseにすることによりショートカットを非表示にできたのですが、ScrollBarでは無理なのでしょうか。
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2008-02-27 16:46
確かに右クリックしたままドロップしたらContextMenuが表示されますね

ScrollBarを継承したりなどすれば、WndProcメソッドでメッセージをフックして
表示させないようにすることはできますが、現状は厳しそうですね、、、。
くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-02-27 20:05
うーん・・・厄介ですね。
右D&D時は、また別のContextMenuを呼び出していますね、、、
(どうも規定ContextMenuしか呼び出していないような)

実現させるには、ガルマ・ザビさんの提言の通り、WndProcにて
WM_RMOUSEDOWNを捕らえて・・って事になるのではないかと思うのですが
このアプローチはDataGridViewから、テコ入れが必要で相当な苦労をしますね。
(そして得られる物が少ない←ガルマ・ザビさん最初のレスの通り)

そこで・・・・・・・
コード:

'' 垂直スクロールバーのContextMenuを非表示にする
Dim vScrBar As VScrollBar = Me.DataGridView1.Controls(1)

'' リフレクションで非パプリックメンバへアクセスします。
Dim type As Type = vScrBar.GetType()

Dim mdEvent As EventInfo = type.GetEvent("MouseDown", _
BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public)

'' 取得したMouseDownイベントにハンドラ追加
mdEvent.AddEventHandler(vScrBar, _
New MouseEventHandler(AddressOf Me.DataGridView_VScrollbar_MouseDownHook))


上記はPage_Loadなどで。

あと、下記メソッドを宣言。
コード:

Private Sub DataGridView_VScrollbar_MouseDownHook( _
ByVal sender As Object, ByVal e As MouseEventArgs)

Dim vScrBar As VScrollBar = CType(sender, VScrollBar)

vScrBar.DoDragDrop(vScrBar, DragDropEffects.None)

End Sub



・・・かなり強引ですが、よろしいですかね。

[コード修正]
見難かったので改行等にて整形

[ メッセージ編集済み 編集者: くまっち 編集日時 2008-02-27 20:15 ]

スキルアップ/キャリアアップ(JOB@IT)