ContextMenuStrip является слишком привлекательной целью для пользовательских всплывающих окон, которые не действуют как контекстное меню. Это желательно, потому что он автоматически выскакивает, когда пользователь щелкает за пределами меню. У него есть ограничения, но он не очень хороший управляющий хост. Проблема щелчка является классической, CMS захватывает мышь, чтобы определить, когда пользователь щелкает за пределами окна.
Это действительно должна быть форма. Чтобы придать ему то же поведение, что и для CMS, требуется немного работы. Вы должны обнаружить щелчки мыши за окном, чтобы вы могли заставить окно исчезнуть. Захват мыши, как CMS, не работает. Одним из приемов является использование IMessageFilter, он позволяет взглянуть на входные сообщения, прежде чем они будут доставлены в окно с фокусом. Вот пример формы, которая реализует это:
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());
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. Функция, а не ошибка.