【问题标题】:Context Menu item must been clicked twice to disappear上下文菜单项必须单击两次才能消失
【发布时间】:2019-09-12 15:14:31
【问题描述】:

我正在列表视图上创建一个上下文菜单,以便能够对特定项目执行功能。右键单击时,上下文菜单正常显示,部分功能执行但不完全,上下文菜单再次显示。

我试图在表单的加载功能中移动上下文菜单创建和绑定,但似乎不起作用...

private JsonReport _lastItemTag;

public Form1()
{
    InitializeComponent();
}

private void ReportTemplateManager_Load(object sender, EventArgs e)
{
    // Initialize context menu for template control
    ContextMenu cm = new ContextMenu();
    cm.MenuItems.Add("Load", new EventHandler(LoadReport_Click));
    template_listview.ContextMenu = cm;
}

private void Template_listview_MouseClick(object sender, MouseEventArgs e)
{
    bool match = false;
    if (e.Button == MouseButtons.Right)
    {
        foreach (ListViewItem item in template_listview.Items)
        {
            if (item.Bounds.Contains(new Point(e.X, e.Y)))
            {
                template_listview.ContextMenu.Show(template_listview, new Point(e.X, e.Y));
                match = true;
                _lastItemTag = item.Tag as JsonReport;
                break;
            }
        }
        if (!match)
            _lastItemTag = null;
    }
}

下面的函数被执行,但没有关闭表单,我必须再次单击它才能关闭上下文菜单和表单本身...

private void LoadReport_Click(object sender, EventArgs e)
{
    if (_lastItemTag != null)
    {
        Console.WriteLine("Loading"); // This get executed
        _lastItemTag = null;
        this.Close(); // This doesnt close the form on the first time
    }
}

我不明白为什么LoadReport 函数可以“部分”执行而不关闭表单。

【问题讨论】:

    标签: c# forms winforms event-handling contextmenu


    【解决方案1】:

    您似乎显示了两次菜单。

    通过将上下文菜单分配给ContextMenu 属性,当您右键单击列表视图时,菜单将自动打开。无需手动显示菜单。

    此外,无需遍历菜单项来查找匹配项。我什至不确定您要通过处理列表视图的MouseClick 事件来做什么。我认为你可以完全消除这种方法。

    菜单项事件处理程序的sender 参数包含被单击的菜单项。您可以直接投射它并从那里获取 Tag 属性:

    private JsonReport _lastItemTag;
    
    public Form1()
    {
        InitializeComponent();
    }
    
    private void ReportTemplateManager_Load(object sender, EventArgs e)
    {
        // Initialize context menu for template control
        ContextMenu cm = new ContextMenu();
    
        //The event handler will be called when this menu item is clicked.
        cm.MenuItems.Add("Load", new EventHandler(LoadReport_Click));
    
        template_listview.ContextMenu = cm;
    }
    
    private void LoadReport_Click(object sender, EventArgs e)
    {
        //The 'sender' argument is the menu item that was clicked
        //In this case, it is the Load menu item so cast the sender
        var menuItem = sender as MenuItem;
    
        //Now get the Tag property and cast it to JsonReport
        _lastItemTag = menuItem.Tag as JsonReport;
    
        if (_lastItemTag != null)
        {
            Console.WriteLine("Loading"); // This get executed
            this.Close(); // This doesnt close the form on the first time
        }
    }
    

    【讨论】:

    • 这个解决方案可能有效,但我对 listview 项标签而不是菜单项感兴趣,所以它不适用于我的情况......
    • 我必须通过将 MouseClick 事件保留在列表视图上来进行一些调整才能存储项目,但是感谢您的回答!
    • 好的,这就解释了一点。不过,我仍然认为您不需要在上下文菜单中调用 Show
    • 我删除了它! MouseClick 函数只获取所选项目并存储它,然后 LoadReport_Click 自己做她的事情!我只是不知道将上下文菜单绑定到控件会自动处理所有点击事件!谢谢你的回答
    猜你喜欢
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多