使用 Infragistics C# Winforms 单击除选项卡之外的任何位置时关闭选项卡

问题描述 投票:0回答:1

在使用 Infragistics、C# 和 WinForms 的 Visual Studio 中,当用户单击表单中的任意位置时如何关闭选项卡?我在同一页面上同时打开了多个表单。当用户单击这些多个表单中的任意位置时,应关闭特定选项卡(假设“DecorDesign”是选项卡名称)。

当选项卡上的焦点丢失时,有什么方法可以关闭选项卡吗?或者这个场景的任何事件处理程序?

c# .net winforms infragistics .net-4.8
1个回答
0
投票

这个答案无论有没有 Infragistics 都应该有效。据我了解,您希望收到应用程序中以任何形式发生鼠标单击的通知,当发生这种情况时,您希望能够检查它以确定单击是否专门发生在“选项卡”(或不是)。如所示,为应用程序的主窗体实现

IMessageFilter
应该给出如图所示的预期行为:

    public partial class MainForm : Form, IMessageFilter
    {
        public MainForm()
        {
            InitializeComponent();
            Application.AddMessageFilter(this);
            Disposed += (sender, e) =>
            {
                Application.RemoveMessageFilter(this);
                OtherForm.Dispose();
            };
            ClickAnywhere += (sender, e) =>
            {
                if (sender is Control clickedOn)
                {
                    switch (clickedOn?.TopLevelControl?.GetType().Name)
                    {
                        case nameof(MainForm): richTextBox.SelectionColor = Color.Green; break;
                        case nameof(OtherForm): richTextBox.SelectionColor = Color.Blue; break;
                        default: richTextBox.SelectionColor = SystemColors.ControlText; break;
                    }
                    string message = $"{clickedOn?.TopLevelControl?.Name}.{clickedOn.Name}{Environment.NewLine}";
                    richTextBox.AppendText(message);
                }
            };
            buttonShowOther.Click += (sender, e) =>
            {
                if (!OtherForm.Visible)
                {
                    OtherForm.Show(this); // Pass 'this' to keep child form on top.
                    OtherForm.Location = new Point(Left + 100, Top + 100);
                }
            };
        }
        OtherForm OtherForm = new OtherForm();

IMessageFilter
的实现由单个方法组成,这里将检测单击“事件”(WM_LBUTTONDOWN消息),以便引发通用自定义事件。

    public bool PreFilterMessage(ref Message m)
    {
        if(m.Msg == WM_LBUTTONDOWN && Control.FromHandle(m.HWnd) is Control control)
        {
            BeginInvoke((MethodInvoker)delegate
            {
                ClickAnywhere?.Invoke(control, EventArgs.Empty);
            });
        }
        return false;
    }
    public event EventHandler ClickAnywhere;
    private const int WM_LBUTTONDOWN = 0x0201;
}

其他形式的模拟示例

public partial class OtherForm : Form
{
    public OtherForm() => InitializeComponent();
    protected override void OnFormClosing(FormClosingEventArgs e)
    {
        if(e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true;
            Hide();
        }
        base.OnFormClosing(e);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.