Close Tab when clicked on anywhere except the tab using Infragistics C# Winforms

49 views Asked by At

In Visual Studio using Infragistics, C#, and WinForms, how to close the tab when the user clicks anywhere in the form? I have multiple forms opened on the same page at the same time. A particular Tab (let's say "DecorDesign" is the tab name) should be closed when the user clicks on anywhere in those multiple forms.

Is there any way to close the tab, when the focus on the tab is lost? Or any event handler for this scenario?

1

There are 1 answers

1
IV. On

This answer should work with or without Infragistics. As I understand it, you want to be notified of a mouse click occurring anywhere in any form of your app and when that happens you want to be able to inspect it to determine whether the click occurred specifically in "the tab" (or not). Implementing IMessageFilter for the main form of your app should give the expected behavior as shown:

mouse click event responses

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);
            }
        };
    }

When you receive the event, look at sender to see if it's a match for "the tab".


The implementation of IMessageFilter consists of a single method, and here the click "event" (the WM_LBUTTONDOWN message) will be detected so that the universal custom event can be raised.

    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;
    OtherForm OtherForm = new OtherForm();
}

Mock example of other forms

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);
    }
}