【问题标题】:Right click menu then item pointing to a class右键单击菜单,然后项目指向一个类
【发布时间】:2012-03-22 15:18:40
【问题描述】:

我希望能够右键单击图像并显示菜单。然后,当我单击其中一个项目时,我希望它指向一个类:

    private void link1add_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
        ContextMenu cm = new ContextMenu();
        cm.MenuItems.Add("Add", HandleContextMenuAdd);
        cm.MenuItems.Add("Remove", HandleContextMenuRemove); 
        link1add.ContextMenu = cm;
        }
    }
        private void HandleContextMenuAdd(object sender, EventArgs e) 
        { 
            MessageBox.Show("Adding");
        }
        private void HandleContextMenuRemove(object sender, EventArgs e)
        {
            MessageBox.Show("Removing");
        }

自首次发布以来已编辑的代码。 谢谢大家的帮助。

【问题讨论】:

  • 指向一个类是什么意思?
  • 例如“如果 (item1_clicked == true) { readocument();}
  • 您的意思是,如果您单击首选项目,它会执行某些操作?
  • 你不想指向一个类,你希望它指向一个类中的一个方法!
  • 没错。但是重新搜索我正在使用的方法(实时创建上下文菜单)它想使用事件而不是带有方法的类。

标签: c# winforms menu right-click


【解决方案1】:

lambda 表达式呢?

cm.MenuItems.Add("Item 2", (_, __) => { 
  if (...) ReadDocument();
});

cm.MenuItems.Add("Item 2", (_, __) => { this.myClassInstance.DoSomething(); });

或者,您可以创建一个带有预期事件处理程序签名的方法:

cm.MenuItems.Add("Item 2", HandleContextMenuClick);

private void HandleContextMenuClick(object sender, EventArgs e)
{
  if (...) ReadDocument();
}

该方法不需要在同一个类中(例如你可以写this.myClassInstance.HandleContextMenuclick)。但我会对其他类隐藏实现细节以避免不必要的耦合。

【讨论】:

  • 我使用了这个方法 - 我无法相信它是多么简单!我有两个处理事件。不确定我是否需要这样做,但我已经相应地更新了我的代码。但是,有可能举办一场活动吗?但是有一个 if 语句或 switch 来选择已选择的项目吗?稍后我将研究 lambda 方法,因为它们看起来确实很有用。谢谢。
  • @Marshal,是的,可以对任意数量的菜单项使用相同的事件。你可以在我的回答中找到。
【解决方案2】:

在此之后您自己的代码的模式:

    public class ReadDocumentEventArgs : EventArgs
    {
        public string ImageInfo { get; set; }
    }

    public void ReadDocument(object sender, ReadDocumentEventArgs ea)
    {
        // do whatever you need to do
        MessageBox.Show(ea.ImageInfo);  // example
    }

    private void link1add_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Right)
        {
            PictureBox imageCtrl = sender as PictureBox;

            // get the information you need to get from your control to identify it
            string imgInfo = "Hello, World!"; // example

            ContextMenu cm = new ContextMenu();
            cm.MenuItems.Add("Item 1");
            cm.MenuItems.Add("Item 2", 
               (EventHandler)((s, rde) => 
               { ReadDocument(s, new ReadDocumentEventArgs() 
                  { ImageInfo = imgInfo }); 
               }));

            link1add.ContextMenu = cm;
        }
    }

在您的 MouseDown 中,您可以使用上面提供的代码创建一个菜单项,该代码将调用名为 ReadDocument 的事件处理程序。请注意,您可以自定义一个 ReadDocumentEventArgs 类以包含必要的属性,这些属性将帮助您识别您单击了哪个图像。

因此,在上面的示例中,MouseDown 中发生的第一件事就是您获得了图像控件的实例(我假设它是一个图片框,但您可以将其转换为实际的任何内容)。

此时,您可以从您的图像中获取文件名或其他任何内容,以从表单上的其他控件中识别它。

接下来,在创建上下文菜单项时,它告诉菜单项调用 ReadDocument,但传入刚刚从图像控件获取的特殊数据。

在 ReadDocument 方法中,您可以做任何您需要做的事情。在我的示例中,我只是抛出了一个 MessageBox 来显示您传入的数据。

【讨论】:

    【解决方案3】:

    您需要的是放置另一个事件处理程序并调用您的 readdocument 方法。

    【讨论】:

    • 这里是个听起来不错的新手。我想打电话给这门课的原因是因为我以前从未处理过创建自己的事件,即使有帮助链接,它们也从未与我想要做的事情相关,所以我无法理解如何根据我的需要创建一个。但是感谢您的帮助。
    • cm.MenuItems.Add("Item 3" new EventHandler(readDocumentMethodNameGoesHere)); 不起作用吗?
    猜你喜欢
    • 1970-01-01
    • 2022-08-14
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多