How to deselect textbox if user clicks elsewhere on the form?
Asked Answered
H

5

6

Currently in my application it is impossible to deselect a textbox. The only way is to select another textbox. My users and I agree that clicking anywhere else on the form should deselect the current textbox. I tried overriding the MouseDown on many controls and having the focus set to a random label but it doesn't work for some controls like the MenuStrip or scrollbars. Any ideas?

Humpbacked answered 26/8, 2011 at 17:21 Comment(6)
What is the rationale for such a requirement? How does this benefit your users?Lurleen
What platform are you using? WinForms, ASP.NET, WPF?Recede
@cdhowie: Because there are also NumericUpDown's on the form and using the mouse wheel on those increment/decrement the value. The user expects to be able to click on a panel and use the scrollwheel to move about it. However, the NumericUpDown is still selected and it scrolls that value instead. I don't want to have this behavior for only NumericUpDown's because it would confuse the user.Humpbacked
Then perhaps clicking the panel should assign focus to its scroll bars.Lurleen
@cdhowie-- I understand why he would want this-- web pages behave this way. Click on a big textarea and your mouse wheel will scroll through the internal text window. Click any where outside of the text area and your mouse wheel will scroll the page. I'd assume he wants his WinForms to behave the same way.Alonsoalonzo
How about another textbox but don't show it and have it selected when the panel is clicked. That is enabled, but not visible, would that work?Bantustan
E
2

Assuming you have no other controls on your forum, try adding a Panel control that can receive focus.

Set the TabIndex on the Panel control to something less than your TextBox or NumericUpDown control has.

Now, when your main form receives focus, the Panel should receive the focus instead of the TextBox area.

ScreenShot

Eller answered 26/8, 2011 at 17:36 Comment(5)
This does not solve my problem. I don't want them to become enabled or disabled, only have them lose focus when the user clicks otherwise. Also, this only detects form clicks and not control clicks on the form.Humpbacked
If the control is disabled, it won't receive mouse messages, and won't receive focus.Bask
Yes but it only disables it (which I do not want) when the user clicks on a blank area on the form.Humpbacked
Are there any other controls on your form that you could give focus to? (I'm guessing not)Eller
Like CKoenig said, you could add another control. A basic Panel would work, that you set your TextBox control on top of, then give the Panel focus. The idea is to send focus somewhere else, because the Tab Index of your TextBox control is (currently) the lowest, forcing it to always take focus whenever the Form gets focus.Eller
C
2

I had a similar issue recently. My interface is very complex with lots of panels and tab pages, so none of the simpler answers I found had worked.

My solution was to programatically add a mouse click handler to every non-focusable control in my form, which would try to focus any labels on the form. Focusing a specific label wouldn't work when on a different tab page, so I ended up looping through and focusing all labels.

Code to accomplish is as follows:

    private void HookControl(Control controlToHook)
    {
        // Add any extra "unfocusable" control types as needed
        if (controlToHook.GetType() == typeof(Panel)
            || controlToHook.GetType() == typeof(GroupBox)
            || controlToHook.GetType() == typeof(Label)
            || controlToHook.GetType() == typeof(TableLayoutPanel)
            || controlToHook.GetType() == typeof(FlowLayoutPanel)
            || controlToHook.GetType() == typeof(TabControl)
            || controlToHook.GetType() == typeof(TabPage)
            || controlToHook.GetType() == typeof(PictureBox))
        {
            controlToHook.MouseClick += AllControlsMouseClick;
        }
        foreach (Control ctl in controlToHook.Controls)
        {
            HookControl(ctl);
        }
    }
    void AllControlsMouseClick(object sender, MouseEventArgs e)
    {
        FocusLabels(this);
    }
    private void FocusLabels(Control control)
    {
        if (control.GetType() == typeof(Label))
        {
            control.Focus();
        }
        foreach (Control ctl in control.Controls)
        {
            FocusLabels(ctl);
        }
    }

And then add this to your Form_Load event:

HookControl(this);
Callihan answered 14/10, 2014 at 1:24 Comment(0)
D
1

Since you probably have a label, or any other control on your winform, I would go with the solution recommended here and just give the focus to a label when the Form gets clicked.

Worst case, you can even add a label situated at the -100, -100 position, set him as the first in the tab order and Focus() it on form click.

Delrio answered 26/8, 2011 at 19:3 Comment(0)
S
0

I have some kind of "workaround" for you. Just but another control (that can get the focus) in the background. I tested this for a GridView (which will paint your control grey) - but you should be able to do it with a custom control in the color you want or just set the backgroundcolor of the gridview (doh). This way everytime the user clicks the background this backgroundcontrol will get the focus.

Sverre answered 26/8, 2011 at 17:42 Comment(1)
This does not work either. It just changes the container for all controls from the form to the panel. The same problem still exists.Humpbacked
R
0

This is generic answer: To deselect TextBoxes when user clicks anywhere else on the form, first make controls to lose focus. For this subscribe to Click Event of the form:

private void Form1_Click(object sender, EventArgs e)
{
    this.ActiveControl = null;
}

Next subscribe your TextBoxes to Focus Leave event and set SelectionLength to 0 (to deselect text, somehow it is not deselected although textbox does not show selection when loses focus):

private void textBoxes_Leave(object sender, EventArgs e)
{
    TextBox txbox = sender as TextBox;
    txbox.SelectionLength = 0;
}

If you have your TexBoxes nested in custom user control, you have to add events within that user control in a similar manner. Hope that helps to anyone else.

Robinson answered 14/2, 2021 at 19:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.