Getting .text from dynamically coded menu

10 posts, 2 answers
  1. KawaUser
    KawaUser avatar
    57 posts
    Member since:
    Oct 2010

    Posted 14 Oct 2010 Link to this post

    I am trying to get the .text property from the programatically added menu items in my click event. I need the .text of the menu item to determine the ID I am putting in to the database table for my report.

    These menu items are generated based on what models we are currently producing. These models are housed in a .txt file in my project. I have it set up this way, because in the future we need to allow easy adding and removing of model numbers and I did not want to set up a database table for 2 - 5 model numbers.

    The first snippet is the code in my click event for the menu item.
    The second snippet is the code I am using to generate my menu items at runtime.
    Private Sub mnuItemModel_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
     
            Dim connStr As String
            connStr = "*****"
     
            Dim insertString = "INSERT INTO REJECT_REPORT (REJECT_ID) SELECT dbo.fnRejectRpt_Next_ID('" + modelNumber + "')"
     
            Dim conn = New SqlConnection(connStr)
            conn.Open()
     
            Dim comm = New SqlCommand(insertString, conn)
            comm.ExecuteNonQuery()
     
            conn.Close()
     
            loadGrid()
     
        End Sub
    Dim mnuItemAdd As New RadMenuItem("&Add")
            Dim mnuItemAddModel As New RadMenuItem("Model")
            mnuItemsTools.Items.Add(mnuItemAdd)
     
            mnuItemAdd.Items.Add(mnuItemAddModel)
     
            AddHandler mnuItemAddModel.Click, AddressOf mnuItemAddModel_click
     
            Dim reader As New System.IO.StreamReader(filePath)
     
            While Not reader.EndOfStream
     
                Dim currentLine As String = reader.ReadLine
     
                Dim mnuItemModel As New RadMenuItem(currentLine)
     
                mnuItemAdd.Items.Add(mnuItemModel)
     
                AddHandler mnuItemModel.Click, AddressOf mnuItemModel_click
     
            End While
  2. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 14 Oct 2010 Link to this post

    Hi,

    This seems to be the simplest thing I can think of off the top of my head that works.
    I dynamically create some menu items, register the click event as you have and then in the click event, see which of the menu items is pressed
    Hope this helps
    Richard
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Dynamically load some menu items
        For i As Integer = 0 To 5
            Dim item As New Telerik.WinControls.UI.RadMenuItem(i.ToString())
            Me.RadMenu1.Items.Add(item)
            AddHandler item.Click, AddressOf menuItem_Click
        Next
    End Sub
    Private Sub menuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
        ' See which item IsPressed
        For Each item As Telerik.WinControls.UI.RadMenuItem In Me.RadMenu1.Items
            If item.IsPressed Then
                MessageBox.Show(item.Text)
                Exit Sub
            End If
        Next
    End Sub

  3. UI for WinForms is Visual Studio 2017 Ready
  4. KawaUser
    KawaUser avatar
    57 posts
    Member since:
    Oct 2010

    Posted 15 Oct 2010 Link to this post

    This would work if I was clicking the main menu item, but the items I am generating are sub items. If there is a way to reach sub items this would definitely work.

    See attached.
  5. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 15 Oct 2010 Link to this post

    Hi, 

    Can you try this... It works with the mouse at least which will give you a good start. If I can do more on it later I will. 
    Let me know if that helps
    Richard
    Imports Telerik.WinControls.UI
    Imports Telerik.WinControls
    Imports System.Collections.ObjectModel
     
    Public Class RadForm1
     
        Private Sub RadForm1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            For i As Integer = 0 To 5
                Dim item As New RadMenuItem(i.ToString())
                Me.RadMenuItem1.Items.Add(item)
                AddHandler item.MouseDown, AddressOf item_mousedown
            Next
        End Sub
     
        Private Sub item_mousedown(ByVal sender As Object, ByVal e As MouseEventArgs)
            For Each item As RadMenuItem In GetRadMenuItems(Me.RadMenuItem1.Items)
                If item.IsPressed Then
                    MessageBox.Show(item.Text)
                End If
            Next
        End Sub
     
        Public Shared Function GetRadMenuItems(ByVal items As Telerik.WinControls.RadItemOwnerCollection) As ReadOnlyCollection(Of RadMenuItem)
            Dim returnControls As New List(Of RadMenuItem)()
            For Each item As RadMenuItem In items
                returnControls.Add(item)
                Dim SubCtrls As ReadOnlyCollection(Of RadMenuItem) = GetRadMenuItems(item.Items)
                returnControls.AddRange(SubCtrls)
            Next
            Dim readOnlyControls As New ReadOnlyCollection(Of RadMenuItem)(returnControls)
            Return readOnlyControls
        End Function
    End Class
  6. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 15 Oct 2010 Link to this post

    Sorry, scrap that. It doesn't work with sub items. Will get back to you when I can
    Richard
  7. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 15 Oct 2010 Link to this post

    Ok - This does work for sub items, but the issue is, you will get the click text back if you click on a menu to open it's sub men too. 

    Try this example and you can get the text back from all of them. But click on "4" to get to "sub" and you get the text for "4" then for "sub"
    Richard
    Imports Telerik.WinControls.UI
    Imports Telerik.WinControls
    Imports System.Collections.ObjectModel
     
    Public Class RadForm1
     
        Private Sub RadForm1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            For i As Integer = 0 To 5
                Dim item As New RadMenuItem(i.ToString())
                Me.RadMenuItem1.Items.Add(item)
                AddHandler item.MouseDown, AddressOf item_MouseDown
                If i = 4 Then
                    Dim subitem As New RadMenuItem("sub")
                    item.Items.Add(subitem)
                    AddHandler subitem.MouseDown, AddressOf item_MouseDown
                End If
            Next
        End Sub
     
        Private Sub item_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
     
            For Each item As RadMenuItem In GetRadMenuItems(Me.RadMenuItem1.Items)
                If item.IsPressed Then
                    MessageBox.Show(item.Text)
                End If
            Next
        End Sub
     
        Public Shared Function GetRadMenuItems(ByVal items As Telerik.WinControls.RadItemOwnerCollection) As ReadOnlyCollection(Of RadMenuItem)
            Dim returnControls As New List(Of RadMenuItem)()
            For Each item As RadMenuItem In items
                returnControls.Add(item)
                Dim SubCtrls As ReadOnlyCollection(Of RadMenuItem) = GetRadMenuItems(item.Items)
                returnControls.AddRange(SubCtrls)
            Next
            Dim readOnlyControls As New ReadOnlyCollection(Of RadMenuItem)(returnControls)
            Return readOnlyControls
        End Function
    End Class
  8. Answer
    Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 15 Oct 2010 Link to this post

    Ok, this might be a stupid question but i'm tired,
    Why don't you just take the text from the sender?

    Like so:
    namespace TestMenuItemText
    {
        using System;
        using System.Windows.Forms;
        using Telerik.WinControls.UI;
     
        public partial class Form1 : Form
        {
            private RadMenu radMenu1;
            public Form1()
            {
                InitializeComponent();
                this.Controls.Add(radMenu1 = new RadMenu());
            }
     
            protected override void OnLoad(EventArgs e)
            {
                base.OnLoad(e);
     
                LoadItems();
            }
     
            private void LoadItems()
            {
                for (int i = 0; i < 10; i++)
                {
                    var parentItem = new RadMenuItem("MenuItem" + i);
                    parentItem.Click += new EventHandler(menuItem_Click);
                    this.radMenu1.Items.Add(parentItem);
                    for (int j = 0; j < 4; j++)
                    {
                        var childFirstLevel = new RadMenuItem("MenuItem" + i + j);
                        childFirstLevel.Click += menuItem_Click;
                        parentItem.Items.Add(childFirstLevel);
                        for (int k = 0; k < 3; k++)
                        {
                            var childSecondLevel = new RadMenuItem("MenuItem" + i + j + k);
                            childSecondLevel.Click += menuItem_Click;
                            childFirstLevel.Items.Add(childSecondLevel);
                        }
                    }
                }
            }
     
            void menuItem_Click(object sender, EventArgs e)
            {
                MessageBox.Show((sender as RadMenuItem).Text);
            }
        }
    }

    Update, forgot to mention, The sender is the Menu Item, not the menu itself.

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga
  9. Answer
    Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 15 Oct 2010 Link to this post

    Oh dear.. I've well and truly tried to over-engineer that one. Must be tired too. 
    Sorry! -and thanks Emanuel
    Private Sub RadForm1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For i As Integer = 0 To 5
            Dim item As New RadMenuItem(i.ToString())
            Me.RadMenuItem1.Items.Add(item)
            AddHandler item.Click, AddressOf item_click
            If i = 4 Then
                Dim subitem As New RadMenuItem("sub")
                item.Items.Add(subitem)
                AddHandler subitem.Click, AddressOf item_click
            End If
        Next
    End Sub
     
    Private Sub item_click(ByVal sender As Object, ByVal e As EventArgs)
     
        MessageBox.Show(DirectCast(sender, RadMenuItem).Text)
    End Sub
  10. KawaUser
    KawaUser avatar
    57 posts
    Member since:
    Oct 2010

    Posted 15 Oct 2010 Link to this post

    I have got it working... All I needed to do was add the direct cast to my event.

    Public Sub loadModels()
     
            Dim filePath As String = "****"
     
            Dim mnuItemAdd As New RadMenuItem("&Add")
            Dim mnuItemAddModel As New RadMenuItem("Model")

            mnuItemsTools.Items.Add(mnuItemAdd)
     
            mnuItemAdd.Items.Add(mnuItemAddModel)
     
            AddHandler mnuItemAddModel.Click, AddressOf mnuItemAddModel_click
     
            Dim reader As New System.IO.StreamReader(filePath)
     
            While Not reader.EndOfStream
     
                Dim currentLine As String = reader.ReadLine
     
                Dim mnuItemModel As New RadMenuItem(currentLine)
     
                mnuItemAdd.Items.Add(mnuItemModel)
     
                AddHandler mnuItemModel.Click, AddressOf mnuItemModel_click
     
            End While
     
        End Sub
     
    Private Sub mnuItemModel_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
     
            MessageBox.Show(DirectCast(sender, RadMenuItem).Text)
     
        End Sub
  11. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 15 Oct 2010 Link to this post

    Glad you have it working. So sorry that I was tired enough to give you that over-cooked solution at the start!
    Best wishes
    Richard
Back to Top
UI for WinForms is Visual Studio 2017 Ready