VB.NET-Tipp 0137: Ein Kontextmenu, welches sich die Öffnungsposition merkt
von Spatzenkanonier
Beschreibung
Meist beziehen sich Aktionen eines Kontextmenüs nicht auf ein Steuerelement insgesamt, sondern auf ein bestimmtes Element darin (beispielsweise ein Treenode, ListViewItem oder eine DatagridViewCell). Im Click-Ereignis kann man den gemeinten Eintrag aber nicht ohne weiteres identifizieren, denn dazu benötigt man die Mausposition zum Zeitpunkt, als das Kontextmenu geöffnet wurde (die Maus wurde nach dem Öffnen ja weiter bewegt, um ein MenuItem anzuwählen).
Hier wird ein ContextMenuStrip vorgestellt, das sich die Position merkt an der es geöffnet wurde.
Schwierigkeitsgrad: | Framework-Version(en): .NET Framework 1.0, .NET Framework 1.1, .NET Framework 2.0, .NET Framework 3.0, .NET Framework 3.5, .NET Compact Framework 1.0, .NET Compact Framework 2.0, .NET Framework 4 | .NET-Version(en): Visual Basic 2002, Visual Basic 2003, Visual Basic 2005, Visual Basic 2008, Visual Basic 2010 | Download: |
' Dieser Quellcode stammt von http://www.activevb.de ' und kann frei verwendet werden. Für eventuelle Schäden ' wird nicht gehaftet. ' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. ' Ansonsten viel Spaß und Erfolg mit diesem Source! ' ############################################################################## ' ############################# ContextMenuEx.vb ############################### ' ############################################################################## Imports System.Drawing Imports System.ComponentModel Namespace System.Windows.Forms <DesignerCategoryAttribute("Code")> _ Public Class ContextMenuEx : Inherits ContextMenuStrip Private _OpenClickLocation As Point Public Sub New() End Sub ''' <summary> ''' the designer uses this constructor to reserve this component ''' as to dispose together with the Form ''' </summary> Public Sub New(ByVal container As IContainer) MyBase.New(container) End Sub ''' <summary> ''' mousePosition over the control, on which the ContextMenuEx ''' last time was opened ''' </summary> Public ReadOnly Property OpenClickLocation() As Point Get Return _OpenClickLocation End Get End Property Protected Overrides Sub OnOpened(ByVal e As EventArgs) If SourceControl IsNot Nothing Then _OpenClickLocation = _ SourceControl.PointToClient(Control.MousePosition) End If MyBase.OnOpened(e) End Sub End Class End Namespace ' ############################################################################## ' ######################### frmContextMenuExTester.vb ########################## ' ############################################################################## Public Class frmContextMenuExTester ' ContextMenues im FormDesigner erstellen: ' 1) ContextMenuEx aus der Toolbox aufs Form ziehen. ' 2) alle MenuItems darin anlegen, und sinnvoll benennen ' 3) Doppelklick auf ein Item öffnet den Form-User-Code im Editor, und ' generiert eine Click-Eventhandler-Sub ' 4) wieder in den FormDesigner wechseln, im EigenschaftenFenster auf ' Events gehen. ' 5) Die Click-Events der anderen MenuItems dem bereits bestehendem ' Eventhandler zuordnen (Das fügt der Handles-Klausel weitere ' Click-Events hinzu) ' 6) Die ContextMenustrip-Property des Ziel-Controls auf das passende ' ContextMenuEx festlegen, damit es sich beim Rechtsklick auf dieses ' Control öffnet ' 7) Im Editor den Eventhandler sinnvoll umbenennen, und die ' Click-Verarbeitung ausprogrammieren Private Sub frmContextMenuExTester_Load(ByVal sender As Object, _ ByVal e As EventArgs) Handles MyBase.Load Me.Location = Screen.PrimaryScreen.WorkingArea.Location TreeView1.ExpandAll() End Sub Private Sub TreeviewMenuItem_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles btAddNode.Click, btDeleteNode.Click Dim nd As TreeNode = TreeView1.GetNodeAt(TreeviewMenu.OpenClickLocation) Select Case True Case sender Is btAddNode Dim Nodes = If(nd Is Nothing, TreeView1.Nodes, nd.Nodes) Nodes.Add("NewNode") If nd IsNot Nothing Then nd.Expand() Case sender Is btDeleteNode If nd Is Nothing Then Return Dim Nodes = If(nd.Parent Is Nothing, _ TreeView1.Nodes, nd.Parent.Nodes) Nodes.Remove(nd) End Select End Sub Private Sub ListboxMenuItem_Click(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles btListItemUp.Click, btListItemDown.Click, _ btRemoveListItem.Click, btInsertListItem.Click Dim Items = ListBox1.Items Dim indx As Integer = _ ListBox1.IndexFromPoint(ListboxMenu.OpenClickLocation) Select Case True Case sender Is btInsertListItem Static count As Integer = 0 Items.Insert(If(indx < 0, Items.Count, indx), "NewItem" & count) count += 1 Case sender Is btRemoveListItem If indx < 0 Then Return Items.RemoveAt(indx) Case sender Is btListItemUp If indx < 1 Then Return Dim itm = Items(indx) Items.RemoveAt(indx) Items.Insert(indx - 1, itm) Case sender Is btListItemDown If indx < 0 OrElse indx = Items.Count - 1 Then Return Dim itm = Items(indx) Items.RemoveAt(indx) Items.Insert(indx + 1, itm) End Select End Sub End Class
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.