C# Checkbox not gaining focus on Tabstop - c#

I am making a config editor form and have hit a bit of an issue, I put a lot of time into userfriendly and efficient design and therefor want the TabIndex to work perfectly to minimize use of mouse.
My problem is now when I try to tab through the controls I noticed the CheckBox was not gaining focus like if you press it with the mouse, this means I couldn't tab through and change their state directly from keyboard.
How do I make the CheckBox gain focus via TabIndex and TabStop so that I can just press Enter to change its state via the KeyUp event.
Below is a picture of my form, and next to it a picture of the TabIndex as well as a the code taken directly from the Form.Designer.cs class.
//
// cbxDefaultPublic
//
this.cbxDefaultPublic.AutoSize = true;
this.cbxDefaultPublic.Location = new System.Drawing.Point(247, 12);
this.cbxDefaultPublic.Name = "cbxDefaultPublic";
this.cbxDefaultPublic.Size = new System.Drawing.Size(15, 14);
this.cbxDefaultPublic.TabIndex = 1;
this.cbxDefaultPublic.TabStop = true;
this.cbxDefaultPublic.UseVisualStyleBackColor = true;
Please note that I had a hard time explaining this cause its a bit complicated and didn't know how to explain it so bare over with me if I got a few things wrong.

With the help of the people commenting on my question I was able to get on the right track of what to do and what to search for.
Thanks to Grant Winney, LarsTech and JohnnyBoy for explaining to me how the CheckBox worked and what I needed to look at.
I found out that the CheckBox does not have a public highlight feature so I had to get creative.
What I did was I created a custom CheckBox and well.. might just show you the code :P
public class MyCbx : CheckBox {
protected override void OnGotFocus(EventArgs e) {
base.OnGotFocus(e);
base.OnEnter(e);
base.OnMouseEnter(e);
}
protected override void OnLostFocus(EventArgs e) {
base.OnLostFocus(e);
base.OnLeave(e);
base.OnMouseLeave(e);
}
protected override void OnMouseLeave(EventArgs e) {
if(!this.Focused) {//prevent it from losing highligh if control is in focus
base.OnMouseLeave(e);
}
}
}
So I call the MouseEnter and Leave events when It gain or lose focus, this will make it change to a highlighted state.

Related

Using MouseHover event and ToolTip

To show the relevant information(in monopoly game, the property belongs which player, current market price etc.), I put a Label on the top of a panel, and used a ToolTip object to display the information. This is the image of my current setup.
Here are the steps I have done:
1.Added MouseHover event handler (The Label name is MEDITERANEAN)
this.MEDITERANEAN.MouseHover += new System.EventHandler(this.MEDITERANEAN_MouseHover);
2.Initialized Tooltip
private void InitializeToolTip()
{
toolTipLabel.ToolTipIcon = ToolTipIcon.Info;
toolTipLabel.IsBalloon = true;
toolTipLabel.ShowAlways = true;
}
3.Call setToolTip() in MouseHover call back function
private void MEDITERANEAN_MouseHover(object sender, EventArgs e)
{
toolTipLabel.SetToolTip(MEDITERANEAN, "You put mouse over me");
rolledDice.AppendText("Mouse Over");
}
But when I start application and move my cursor over the label, there is no text from toolTipLabel. What part did I make mistakes?
Interestingly, i made other function and it works.
private void panelBoard_MouseOver(object sender, EventArgs e)
{
toolTipLabel.SetToolTip(panelBoard, "You put mouse over me");
rolledDice.AppendText("Mouse Over");
}
I think you just need to bring your lable control in front of image. Try something like this .
MEDITERANEAN.BringToFront();
I found the solution, first I should set Panel's property "Enable" to true, then set label's property "visible" to true as well.

How do I set focus to a Usercontrol

I have 50 UserControls that I add to a flowlayoutPanel dynamically.
I need to set focus to a user control but it doesn't work.
I have been searching a lot but can't find any example that I understand.
The only example that I find is this
Setting Focus to a .NET UserControl...?
I tried to use userCtrl.Focus(); but it didn't work.
As I have been reading the usercontrol doesn't like to have focus.
Addition: Now that I understand more of the Control class, I
understand that if you derive from Control you should not subscribe
to its events, but use the On.. functions, like OnEnter. I've
changed my answer accordingly
To Activate any Control, including a UserControl use Control.Select().
If you do this for a TextBox, you'll see that Select ensures that it gets the input focus.
I guess you want to do something with the selected UserControl (the Control that has the focus), for instance, you want to change its appearance, or select any of the controls on it. To do this, your UserControl class has to subscribe to the events Control.Enter and Control.Leave
I have created a UserControl with a CheckBox that is automatically checked whenever the UserControl is selected (has the input focus):
Addition: If you derive from a Control, don't subscribe to events Enter and Leave. Instead override the functions that raise these events: OnEnter / OnLeave.
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
protected override void OnEnter(EventArgs e)
{
this.checkBox1.Checked = true;
base.OnEnter(e); // this will raise the Enter event
}
protected override void OnLeave(EventArgs e)
{
this.checkBox1.Checked = false;
base.OnLeave(e); // this will raise the Leave event
}
}
I have a form with a button, and an event handler that is called when the button is clicked:
private void OnButton1Clicked(object sender, EventArgs e)
{
this.userControl1.Select();
}
Now whenever the button is clicked I see that the user control gets the focus because the check box is checked and whenever I click elsewhere the checkbox is unchecked.
You can set focus to a control by using the ActiveControl Property
this.ActiveControl = myUserControl;
Though you did not detail what did you mean it did not work, focusing has many aspects conventionally.
1. Explicit focusing
Calling Focus() method of a control is the same as setting ActiveControl of the container form. If CanFocus returns true (your control and all its parents are visible and enabled), it works; however, you will have no visual feedback, except some indirect hint, eg. the originally focused control (button or textbox) loses the focus.
To visualize the focused state you might want to use some custom paint:
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.Clear(Focused ? SystemColors.Highlight : SystemColors.Control);
}
If you derive directly from Control instead of UserControl, override the following two methods to force a repaint on changing the focused state:
protected override void OnGotFocus(EventArgs e)
{
Invalidate();
base.OnGotFocus(e);
}
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
Invalidate();
}
2. Focusing by the mouse
To receive focus by clicking the control add this line to the constructor:
SetStyle(ControlStyles.Selectable, true);
If you derive directly from Control instead of UserControl, override the OnMouseDown, too:
protected override void OnMouseDown(MouseEventArgs e)
{
if (!Focused)
Focus();
base.OnMouseDown(e);
}
3. Focusing by the keyboard
To receive focus by the TAB key just set the TabStop property to true and adjust the TabOrder property.
Example to focus on textBox1:
textBox1.Select();
you can try tab index of the user control. If you set its tab index to 1 it will be focused once the program start.

Defocusing TextBox by clicking it again

I'm making a settings form, where user can assign custom hotkeys for the application. There's a TextBox, and by clicking it with mouse, it focuses and waits for one keypress and then defocuses (by focusing another label):
private void txtKey_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
private void txtKey_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
TextBox textBox = (TextBox)sender;
textBox.Text = e.KeyCode.ToString();
label1.Focus();
}
Is there a way to defocus focused TextBox (and cancel the key assinging process), by either clicking it again with mouse, or by clicking the GroupBox around it? I can't figure out how to check if TextBox was already focused when clicked (because when clicked, it gets focused before I can test if it's focused). Of course I can add a button "Cancel" next to the TextBox, but that's not what I want.
There is no Click-event for GroupBox, so I can't defocus TextBox by clicking GroupBox around it. Or can I somehow?
You can set/remove the Focus with
Keyboard.Focus = null;
You can also register to the following event:
public event MouseButtonEventHandler PreviewMouseLeftButtonDown
This event fires every time you click on the TextBox, thus you can set the Focus there if you want to.
For Winforms there is a way as well. I'm not proficient in it, but here would be a way:
Make a textBox (e.g. named textBoxFocus) that lies outside your window. Size it 1, 1 and move it to -10,-10 for example. Then you can register to the Click event and write
textBoxFocus.Focus();
It's a bit of a roundabout way, but should achieve what you want.
Thanks to private_meta for getting me to right direction (in comments)! I set the flag with click event, and before setting the flag, testing if flag is set. So first click does not find the flag, but second will. And flag is cleared within textbox Enter-event (which fires before Click-event). Now every other click focuses and every other defocuses textbox, as I wanted.
private void txtKey_Enter(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
textBox.Tag = null;
}
private void txtKey_Click(object sender, EventArgs e)
{
TextBox textBox = (TextBox)sender;
if (textBox.Tag != null) label1.Focus();
textBox.Tag = "clicked";
}
One of the simple way is that, you may use a bool flag here.
Algorithm:
By default, the bool value is 0;
If(Textbox Selected && flag = 0)
Do your task; and flag = 1;
I hope I could satisfy your query and you can follow this algorithm.

C# WinForms showing a control as a dropdown

Gretings
I need to have a custom control for my application. Basically its an expression editing GUI. You have, say, expression:
If variable_x is greater than variable_y
And you can click on "greater than" and change it to other comparator (like, equal to or less than).
The control thus must look like a label, but when you click it, it must show a dropdown (like combobox does) that has a listview inside (or maybe some other control) so that user can choose something. In a sense, i need a combobox without the box itself, replaced by something else (in this case, a label).
I know how to make custom controls, i understand i must somehow DropDown on mouse click or enter keypress, and hook events so that when whatever i dropped has closed, the choice is made, and also somehow track if user clicked elsewhere so i can close this dropdowned control. But i dont know if this is easy to do (some built-in method exists) or i have to do it all myself? Dont want to redevelop the wheel....
Please tell me if there are easy ways to do this.
Thanks!
You can extend the ComboBox control to update the DropDownStyle on Enter and LostFocus events.
public partial class MyComboBox : ComboBox
{
public MyComboBox()
{
InitializeComponent();
this.Dock = DockStyle.Fill;
this.SelectionChangeCommitted += this.OnComboBoxSelectionChangeCommitted;
this.Enter += this.OnControlEnter;
this.LostFocus += this.OnComboBoxLostFocus;
}
private void OnControlEnter(object sender, EventArgs e)
{
this.DropDownStyle = ComboBoxStyle.DropDownList;
}
private void OnComboBoxLostFocus(object sender, EventArgs e)
{
this.DropDownStyle = ComboBoxStyle.Simple;
}
private void OnComboBoxSelectionChangeCommitted(object sender, EventArgs e)
{
// Notify to update other controls that depend on the combo box value
}
}

How to detect if an event is sent by an argument

I don't know if it is called an argument (i.e. textbox1.text = "Hello";).
I have a control and there is a text box in it. It has a dropdown box that opens when the text is changed. But when I update the text in the text box that box drops down.
I need a way to make it so it only drops down if someone manually does it.
TBAddressBar.ABText.Text = getCurrentBrowser().Source.ToString();
and
public void ABText_TextChanged(object sender, TextChangedEventArgs e)
{
if (sender == 1*)
{
ABDropDown.Visibility = Visibility.Visible;
}
else
{
ABDropDown.Visibility = Visibility.Collapsed;
}
}
If someone manually does it, presumably they are using keypresses to do so. In that case, use KeyDown or KeyUp events to show the dropdown instead.
What I have done in the past is use a boolean variable that I set when I update my textboxes programically to bypass the TextChangedEvent.
i.e.
bool loading;
....
loading =true;
TBAddressBar.ABText.Text = getCurrentBrowser().Source.ToString();
loading = false;
public void ABText_TextChanged(object sender, TextChangedEventArgs e)
{
if(loading) return;
....
}
Simple, just remove the code from your TextChanged Event.
Anyway you got the basic idea.. Now do your dropdown logic in KeyPress event, since it accepts only characters and not the modifiers. So it behaves closer to your requirement. Not that you cant handle the same using KeyDown and KeyUp, you can, but more code..

Categories