This is a migrated thread and some comments may be shown as answers.

Getting .text from dynamically coded menu

9 Answers 108 Views
Menu
This is a migrated thread and some comments may be shown as answers.
KawaUser
Top achievements
Rank 2
KawaUser asked on 14 Oct 2010, 07:15 PM
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

9 Answers, 1 is accepted

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 14 Oct 2010, 11:04 PM
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

0
KawaUser
Top achievements
Rank 2
answered on 15 Oct 2010, 01:56 PM
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.
0
Richard Slade
Top achievements
Rank 2
answered on 15 Oct 2010, 02:24 PM
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
0
Richard Slade
Top achievements
Rank 2
answered on 15 Oct 2010, 02:30 PM
Sorry, scrap that. It doesn't work with sub items. Will get back to you when I can
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 15 Oct 2010, 02:50 PM
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
0
Accepted
Emanuel Varga
Top achievements
Rank 1
answered on 15 Oct 2010, 02:51 PM
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
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 15 Oct 2010, 02:54 PM
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
0
KawaUser
Top achievements
Rank 2
answered on 15 Oct 2010, 04:05 PM
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
0
Richard Slade
Top achievements
Rank 2
answered on 15 Oct 2010, 04:39 PM
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
Tags
Menu
Asked by
KawaUser
Top achievements
Rank 2
Answers by
Richard Slade
Top achievements
Rank 2
KawaUser
Top achievements
Rank 2
Emanuel Varga
Top achievements
Rank 1
Share this question
or