在一个单一的ContextMenuItem .NET多个ToolStripButtons [英] .NET Multiple ToolStripButtons in a single ContextMenuItem

查看:192
本文介绍了在一个单一的ContextMenuItem .NET多个ToolStripButtons的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个文本菜单,其中菜单中的某些项目包含一个以上的项目。你可以把它看作是试图一个ToolStrip的和的ContextMenuItem结合。 我使用的是ToolStripControlHost试过了,但是这造成的问题为重点。它基本上需要你点击一切都在ToolStrip的两倍。

I'm trying to create a ContextMenu where some items in the menu contain more than a single item. You could see it as trying to combine a ToolStrip and ContextMenuItem. I've tried using a ToolStripControlHost, but this creates problems with the focus. It basically requires you to click everything in the ToolStrip twice..

ContextMenuStrip m = new ContextMenuStrip();
ToolStrip tStrip = new ToolStrip(new ToolStripDropDownButton(), new ToolStripButton());
ToolStripControlHost tsHost = new ToolStripControlHost(tStrip);
m.Items.Add(tsHost);

在如何实现这一目标有什么想法?

Any thoughts on how to achieve this?

推荐答案

一个的ContextMenuStrip是太有吸引力了一个定制的弹出窗口没有像上下文菜单目标。它是理想的,因为它在用户点击菜单以外自动弹出下来。它有它的局限性,虽然,它只是是不是一个很好的控制主机。点击问题是经典的,CMS捕获鼠标,当用户在窗口中点击外检测。

A ContextMenuStrip is too attractive a target for custom popup windows that don't act like a context menu. It is desirable because it automatically pops down when the user clicks outside of the menu. It has limitations though, it just isn't a very good control host. The click problem is classical one, CMS captures the mouse to detect when the user clicks outside of the window.

这真的应该是一种形式。为了给它相同的行为作为一个CMS需要一些工作,但。你要检测鼠标点击是关闭窗口,这样就可以使窗口消失。捕获鼠标类似CMS并不起作用。一招是使用IMessageFilter,它可以让你快来看看输入消息之前,它们被传递到与焦点的窗口。下面是实现此示例的形式:

This really ought to be a form. To give it the same behavior as a CMS requires a bit of work though. You have to detect mouse clicks that are off the window so you can make the window disappear. Capturing the mouse like CMS does doesn't work. One trick is using IMessageFilter, it lets you take a peek at input messages before they are delivered to the window with the focus. Here's a sample form that implements this:

public partial class MyContextMenu : Form, IMessageFilter {
    public MyContextMenu() {
        InitializeComponent();
        Application.AddMessageFilter(this);
    }
    protected override void OnFormClosed(FormClosedEventArgs e) {
        Application.RemoveMessageFilter(this);
        base.OnFormClosed(e);
    }
    public void Show(Control ctl, Point pos) {
        this.StartPosition = FormStartPosition.Manual;
        this.Location = ctl.PointToScreen(pos);
        while (!(ctl is Form)) ctl = ctl.Parent;
        this.Show((Form)ctl);
    }
    public bool PreFilterMessage(ref Message m) {
        // Detect mouse clicks outside of the form
        if (m.Msg == 0x201 || m.Msg == 0x204 || m.Msg == 0x207 || 
            m.Msg == 0xA1  || m.Msg == 0xA4  || m.Msg == 0xA7) {
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            Control ctl = Control.FromHandle(m.HWnd);
            if (ctl != null) pos = ctl.PointToScreen(pos);
            pos = this.PointToClient(pos);
            if (pos.X < 0 || pos.Y < 0 || pos.X >= this.Width || pos.Y >= this.Height) {
                this.Close();
            }
        }
        return false;
    }
}

使用设计者正常设计形式。你想,至少给它一个不同的FormBorderStyle。使用随机提供的Show()方法重载,你使用它的CMS以同样的方式。请注意,持久性有机污染物的形式下,只有当你点击那个年代由应用程序拥有的,不像一个CMS的窗口。功能,不是一个错误。

Use the designer as normal to design the form. You want to at least give it a different FormBorderStyle. Use the provided Show() method overload the same way you use it for CMS. Do note that the form pops down only when you click on a window that's owned by the application, unlike a CMS. Feature, not a bug.

这篇关于在一个单一的ContextMenuItem .NET多个ToolStripButtons的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆