C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

コンテキストメニューにチェックを付ける方法

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■93747 / inTopicNo.1)  コンテキストメニューにチェックを付ける方法
  
□投稿者/ 板前 (1回)-(2020/01/25(Sat) 21:32:31)

分類:[.NET 全般] 

VB.NETを使っています。

Chart上で右クリックすると、コンテキストメニューが表示され、
それをクリックすることでチェックボックスがオンオフされるプログラムを作りたいと考えています。

右クリックでコンテキストメニューを表示するには

    Private Sub Chart1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseDown

        If e.Button = MouseButtons.Right Then

            Dim cms As New ContextMenuStrip
            Dim item1 As ToolStripItem = cms.Items.Add("AAA")
            item1.Tag = 1
            AddHandler item1.Click, AddressOf menuChoice


            Dim item2 As ToolStripItem = cms.Items.Add("BBB")
            item2.Tag = 2
            AddHandler item2.Click, AddressOf menuChoice

            cms.Show(Chart1, e.Location)

            ' CType(cms.Items(1), ToolStripMenuItem).Checked = True


        End If

    End Sub

のようにして実現することができました。
チェックボックスの表示・非表示は
CType(cms.Items(1), ToolStripMenuItem).Checked = True
で切り替えることができます。

後は、クリックした項目のチェックボックスだけが表示・非表示されるようにしたいのですが、


    Private Sub menuChoice(ByVal sender As Object, ByVal e As EventArgs)

        Dim item As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)

        For Each s As ToolStripMenuItem In CType(sender, ToolStripItem).Owner.Items

            If s IsNot Nothing Then

                If s Is item Then

                    s.Checked = True      'Not s.Checked
                    s.CheckState = CheckState.Checked

                End If

            End If

        Next s

    End Sub

のようにしても、チェックボックスが表示されません。

どのようにすれば、選択した項目のチェックボックスを有効化することができますか?


引用返信 編集キー/
■93748 / inTopicNo.2)  Re[1]: コンテキストメニューにチェックを付ける方法
□投稿者/ Azulean (1131回)-(2020/01/26(Sun) 08:46:01)
No93747 (板前 さん) に返信
>             Dim cms As New ContextMenuStrip
>             Dim item1 As ToolStripItem = cms.Items.Add("AAA")
>             item1.Tag = 1
>             AddHandler item1.Click, AddressOf menuChoice

チャートをクリックする度に、新しい ContextMenuStrip、新しい ToolStripMenuItem を作っているので、
menuChoice で Checked プロパティを操作しても、その操作した ToolStripMenuItem は消滅しています。

方法としては 2 通り考えられます。


[1] menuChoice では「どれをクリックしたか」を覚えておき、次回のチャートクリック時に参照する
何を覚えておけば良いかはあなた自身で決める必要はありますが、「どのメニューかを判断できる情報」を覚えておく形です。
たとえば、このサンプルだとメニューの名前や Tag プロパティが候補になりそうです。

Private lastClickedMenuTag As Integer

Private Sub menuChoice(ByVal sender As Object, ByVal e As EventArgs)
  Dim item As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
  lastClickedMenuTag = CInt(item.Tag)
End Sub


Private Sub Chart1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseDown
  If e.Button = MouseButtons.Right Then
    Dim cms As New ContextMenuStrip
    Dim item1 As ToolStripItem = cms.Items.Add("AAA")
    item1.Tag = 1
    AddHandler item1.Click, AddressOf menuChoice

    If lastMenuClickedTag = 1 Then
      item1.Checked = True
    End If
   '以下略


[2] 毎回動的にメニューを作らず、デザイナでコンテキストメニューを作る
こっちの形では Chart1_MouseDown で動的にメニューを作り上げているところを削除し、デザイナで ContextMenuStrip を配置し、メニューを作ります。
毎回作成し直さなくなるので、メニュークリック時の処理は今のコードを流用できます。

引用返信 編集キー/
■93749 / inTopicNo.3)  Re[2]: コンテキストメニューにチェックを付ける方法
□投稿者/ 板前 (2回)-(2020/01/26(Sun) 11:58:30)
ありがとうございます。

2つめの方法に関してなのですが、
デザイナでツールボックスからContextMenuStripを追加することもできますが、

Private ContextMenuStrip1 As New ContextMenuStrip

のようにして、Form1 Classの中にプライベート変数を定義しても追加することができると思います。

これらは全く同じものと考えて良いのでしょうか?

MenuStripだと、

Private MenuStrip1 As New MenuStrip

と定義しても使うことができないので、ツールボックス上に配置するのは理解できますが、
ContextMenuStripは、プライベート変数でも使えるのなら
ツールボックス上で使う必要はないのではないでしょうか?


引用返信 編集キー/
■93750 / inTopicNo.4)  Re[3]: コンテキストメニューにチェックを付ける方法
□投稿者/ Azulean (1132回)-(2020/01/26(Sun) 12:50:43)
No93749 (板前 さん) に返信
> 2つめの方法に関してなのですが、
> デザイナでツールボックスからContextMenuStripを追加することもできますが、
>
> Private ContextMenuStrip1 As New ContextMenuStrip
>
> のようにして、Form1 Classの中にプライベート変数を定義しても追加することができると思います。
> これらは全く同じものと考えて良いのでしょうか?

今回の本質(インスタンスの違いを意識し、同じインスタンスを使うように改修する)という視点に絞れば同じことです。

デザイナで扱う場合、普段見えるコードとは別の Designer.vb に変数の作成、プロパティやイベントの設定コードが分離され、UI 構築のためのコードを普段見なくて済むようになります。
これは「見るべき・気にするべきコードを減らす」ということのほか、ローカライズ時にまとめて扱えるなど、複数のメリットがあります。

逆にできるだけコードで組み立てたいということや動的なメニューの追加などのニーズがあることも理解はできるので、どちらが良いと言い切るものではありませんね。

> MenuStripだと、
>
> Private MenuStrip1 As New MenuStrip
>
> と定義しても使うことができないので、ツールボックス上に配置するのは理解できますが、
「メニュー」はインスタンスを生成するだけでなく、Form にそのメニューを使うように設定しないといけませんが、それが漏れている…だけではないですか?
デザイナで設定したものは、基本的に裏側でコードが生成されますので、デザイナでできることのほとんどはコードでも書けます。
(それが優れているかは別として)
引用返信 編集キー/
■93751 / inTopicNo.5)  Re[4]: コンテキストメニューにチェックを付ける方法
□投稿者/ 板前 (3回)-(2020/01/26(Sun) 22:12:45)
ご回答どうもありがとうございました。

解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ