vb.netdynamicmenuaddress-operator

dynamic database driven menus in VB.Net


I'm trying to construct a database driven VB.Net app that pulls a list of registered accounts from a database and displays the usernames of throes accounts in menu, so the user can select one and a new form open (where they work with it).

what I have so far is the constructor for the MDI parent window

Public Sub New()

    InitializeComponent()

    Dim tsmi As New ToolStripMenuItem("Users", Nothing, AddressOf users_mousedown)
    MenuStrip1.Items.Add(tsmi)

End Sub

The handler for the user menu (where SQLite_db is a class that looks after the database and user_class is a class with two items (username and password) as strings.

Sub users_mousedown()

    Dim submenu As New ContextMenuStrip
    Dim database As New SQLite_db

    Dim user_list As New List(Of user_class)
    user_list = database.List_Users

    For Each user As user_class In user_list
        submenu.Items.Add(user.username, Nothing, AddressOf Open_new_window(user))
    Next

    submenu.Items.Add("Add new user", Nothing, AddressOf AddNew)
    submenu.Show(Control.MousePosition)

End Sub

What I want to happen is when a user clicks on the context menu a new MDI child form is created and the data in user is passed, however because AddressOf doesn't like passing data this doesn't work...

I've looked at delegates and landa expressions but don't think either of them do what I need, the other option is to make my own subclass of the ContextMenuStrip class, which 1) handles the clicks the way I want to and 2) sounds like a nightmare.

Before I launch into what I think will be a hell of a lot of work, am I missing something? is their a simple way to do what I want to do? or if not will sub-classing ContextMenuStrip work and if not any ideas as to what will (and if it will, any ideas as to how to start learning how to do that)


Solution

  • A simple way to encapsulate user info is with a Helper Class, where you store the context info.

    
    Public Class Question1739163
        Class HelperUserCall
            Public userId As String
    
            Sub New(ByVal id As String)
                userId = id
            End Sub
    
            Public Sub OnClick()
                MsgBox(Me.userId)
            End Sub
        End Class
        Private Sub Question1739163_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Dim t As New ToolStripMenuItem("Users", Nothing, AddressOf user_mousedown)
            MenuStrip1.Items.Add(t)
        End Sub
    
        Public Sub user_mousedown()
            Dim s As New ContextMenuStrip
            Dim a As HelperUserCall
    
            a = New HelperUserCall("u1")
            s.Items.Add(a.userId, Nothing, AddressOf a.OnClick)
    
            a = New HelperUserCall("u2")
            s.Items.Add(a.userId, Nothing, AddressOf a.OnClick)
    
            s.Items.Add("New User", Nothing, AddressOf add_new)
            s.Show(Control.MousePosition)
        End Sub
    
        Sub add_new()
            MsgBox("add new")
        End Sub
    End Class
    

    You could improve the helper class adding the reference to database in the constructor, and retrieving the user info when the user click into the option.