Программное создание контекстного меню


Мне нужно программно создать контекстное меню, используя названия для пунктов меню, которые не известны до тех пор, пока программа загружает пользовательские данные.

Вот как я реализовал это. Я не доволен литой, чтобы получить текст пункта меню, чтобы выяснить, какой элемент они нажали на. Есть ли лучший способ, что я упускаю?

public partial class Form1 : Form
{
    private readonly string[] cards = new string[] {"HBOS", "EGG", "RBOS"};

    ContextMenu mnuContextMenu = new ContextMenu();

    private void Form1_Load(object sender, EventArgs e)
    {
        ContextMenu = mnuContextMenu;

        SetupRightClickmenu();
    }

    private void SetupRightClickmenu()
    {
        MenuItem bank1MenuItem = new MenuItem(BankNames.Bank1);
        MenuItem bank2MenuItem = new MenuItem(BankNames.Bank2);
        MenuItem bank3MenuItem = new MenuItem(BankNames.Bank3);
        MenuItem cashMenuItem = new MenuItem("Cash");
        MenuItem creditCardMenuItem = new MenuItem("Credit Card");

        bank1MenuItem.Click += bank1MenuItem_Click;
        bank2MenuItem.Click += bank2MenuItem_Click;
        bank3MenuItem.Click += bank3MenuItem_Click;
        cashMenuItem.Click += cashMenuItem_Click;

        mnuContextMenu.MenuItems.Add(bank1MenuItem);
        mnuContextMenu.MenuItems.Add(bank2MenuItem);
        mnuContextMenu.MenuItems.Add(bank3MenuItem);
        mnuContextMenu.MenuItems.Add(cashMenuItem);
        mnuContextMenu.MenuItems.Add(creditCardMenuItem);


        MenuItem creditCardSubMenuItem;

        foreach(string card in cards)
        {
            creditCardSubMenuItem = new MenuItem();
            creditCardSubMenuItem.Text = card;
            creditCardMenuItem.MenuItems.Add(creditCardSubMenuItem);
            creditCardSubMenuItem.Click += creditCardSubMenuItem_Click;
        }
    }

    void creditCardSubMenuItem_Click(object sender, EventArgs e)
    {
        MenuItem menuItem = (MenuItem) sender;

        MessageBox.Show("You clicked on " + menuItem.Text);
    }

    void cashMenuItem_Click(object sender, EventArgs e)
    {
        MessageBox.Show("You clicked on cash");
    }

    void bank3MenuItem_Click(object sender, EventArgs e)
    {
        MessageBox.Show("You clicked on bank 3");
    }

    void bank2MenuItem_Click(object sender, EventArgs e)
    {
        MessageBox.Show("You clicked on bank 2");
    }

    void bank1MenuItem_Click(object sender, EventArgs e)
    {
        MessageBox.Show("You clicked on bank 1");
    }
}

Текущая версия массива карт, полученных из данных пользователей.



41056
5
задан 9 августа 2011 в 01:08 Источник Поделиться
Комментарии
3 ответа

Вы можете использовать свойство tag для хранения карт. Нормальный для сохранения контекста объекта в теге.

таким образом, вы можете сделать текст, что вам нравится, например..

creditCardSubMenuItem.Text = string.Format("The card {0}", card);
creditCardSubMenuItem.Tag= card;

4
ответ дан 10 августа 2011 в 01:08 Источник Поделиться

Хотя есть в этом и другие вещи, я не уверен, сделаны в идеальном мода, я не уверен, что весь объем, так что я буду придерживаться только то, что вы просили:

Этот литой от отправителя к определенному типу, который является единственным видом, который будет срабатывать на событие, это стандартный способ делать именно то, что вы делаете с ним. Единственный способ люди делают это, заключается в использовании в качестве которого будет возвращать null, если не удается выполнить приведение, но это должно только использоваться, когда есть шанс, другого типа, чем ожидалось. Если вы знаете наверняка, что обработчик события будет только подписался на объект типа MenuItem в, то гипс-это абсолютно правильный способ сделать это.

2
ответ дан 9 августа 2011 в 04:08 Источник Поделиться

Вы можете сделать что-то подобное. Здесь, я суб класса MenuItem и переопределяется событием onclick. При нажатии на меню, я готовлю в аргументы события и передают его обратно в основную форму. Если вы хорошо с литья 'отправитель' объект, вы можете избавиться от класса MenuActivatedEventArgs. Этот код компилируется, как я вставить его из моего редакторе VisualStudio. Спросите меня, если вы не ясны на любой линии.

Это, вероятно, не лучший способ сделать это, но это, как я люблю реализовывать, когда вещи сходят с ума. Я отделяю их и искать места, где я могу применить некоторые чистые-кодирования и рефакторинг.

using System;
using System.Windows.Forms;

namespace ContextMenu {
public partial class Form1 : Form
{
// info text for message box
private const string InfoText = "You clicked on {0}";
private readonly string[] MyCards = new[] { "HBOS", "EGG", "RBOS" };

public Form1()
{
InitializeComponent();
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// set the context menu
ContextMenu = new System.Windows.Forms.ContextMenu();
// setup menuitems
SetupRightClickMenu();
}

private void SetupRightClickMenu()
{
// add first few menu items which don't have any submenuitems
ContextMenu.MenuItems.AddRange(
new[]
{
CreateAndHookUpMenuItem("Bank 1"),
CreateAndHookUpMenuItem("Bank 2"),
CreateAndHookUpMenuItem("Bank 3"),
CreateAndHookUpMenuItem("Cash"),

});

// create creditcard menu item
var creditCardMenuItem = CreateAndHookUpMenuItem("Credit Card") ;

// add cards to creditcard menu item
foreach (var card in MyCards)
creditCardMenuItem.MenuItems.Add(CreateAndHookUpMenuItem(card));

// finally, add creditcard menu item to the context menu
ContextMenu.MenuItems.Add(creditCardMenuItem);
}

private MenuItem CreateAndHookUpMenuItem(string title)
{
var menuItem = new MyMenuItem(title);
menuItem.OnMenuActivated += MyMenuItem_OnMenuActivated;
return menuItem;
}

private void MyMenuItem_OnMenuActivated(object sender, MenuActivatedEventArgs e)
{
MessageBox.Show(String.Format(InfoText, e.ItsMenuItem.Text));
}
}

class MyMenuItem : MenuItem
{
public MyMenuItem(string title) : base(title) { }

// this can be just of type EventArgs but if you hate casting, this is one way of doing it
public event EventHandler<MenuActivatedEventArgs> OnMenuActivated;

protected override void OnClick(EventArgs e)
{
base.OnClick(e);
InvokeMenuActivatedEvent();
}

private void InvokeMenuActivatedEvent()
{
var handler = OnMenuActivated;
if (handler != null)
{
OnMenuActivated.Invoke(this, new MenuActivatedEventArgs(this));
}
}
}

class MenuActivatedEventArgs : EventArgs
{
public MyMenuItem ItsMenuItem { get; private set; }

public MenuActivatedEventArgs(MyMenuItem item)
{
ItsMenuItem = item;
}
}
}

0
ответ дан 11 августа 2011 в 09:08 Источник Поделиться