Changing the AcceptButton depending on active control - c#

I have a working WinForm that handles the search functionality in my customer database. It contains the following controls:
A textBox where you type your search string (A)
A "search" button (B)
A DataGridView (C) that returns the result of the search
An "OK" button (D) and a "Cancel" button (E)
What I am trying to accieve next is this:
When A is active the AcceptButton (enter) should be linked to B
When B or enter is pressed C should become active
When C is active the AcceptButton should be linked to D
I realise this is a somewhat big question so don't hesitate to answer just one of the bullet marks if you know the answer.
EDIT: I have solved the implementation of requirement 1 and 3 above, but I am still looking for an answer to the second one. To clarify, when the search is initiated (meaning i have pressed enter on the keyboard or the search button with the mouse) I want focus to shift to the first line in the DataGridView.

When you get the text changed event for textBox set the AcceptButton to be "Search":
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.AcceptButton = SearchButton;
}
There will probably want to be more code in here, checking the length of the string etc.
Then once you've done the search and filled in the DataGridView you can then set the AcceptButton to be "OK".
private void dataGridView1_DataMemberChanged(object sender, EventArgs e)
{
this.AcceptButton = OKButton;
}
Though you probably wouldn't want to use this event.
"Cancel" is always the CancelButton.
EDIT: OK for part 2 you want the following code:
private void SearchButton_Click(object sender, EventArgs e)
{
dataGridView1.Focus();
}
This will make it active as soon as the search button is pressed, but you probably want to do it when the DataGridView has been populated - just in case the search returned no results.

Setup handlers to track the Control.Enter event for the particular controls. When the enter is reached try:
this.AcceptButton = ControlThatShouldBeAcceptButton;

You should implement an event listener to DataGridViewBindingCompleteEventHandler. In that event you could add the following code:
{
if(grid.Rows.Count > 0)
{
grid.ClearSelection();
grid.Rows[0].Selected = true;
}
grid.Focus();
}

private void WhateverControl_Enter(...)
{
this.AcceptButton = myButton;
}

Related

how to retrieve text of buttons clicked in windows form with one single method

I have a windows form application with multiple buttons. I need to retrieve the text property of any button clicked in order to create a query to the database. the only way I know is to create a button click event and cast the sender as button then do a switch case for each button Id which seems very hectic since I probably will have more than 100 buttons in the entire application. So my question is there a generic key press method I can create which can retrieve the text property of any button pressed/clicked on the form? Please excuse me if the question is not very clear. Any help will be appreciate
Use a single click event handler for all similar kind of buttons. This way there will be click event subscribed for every button but only one method which will be executed for all buttons. You can determine which button was pressed as follows.
Using sender object as follows;
private void button_Click(object sender, EventArgs e)
{
var buttonText = ((Button)sender).Text;
//Query using buttonText
}
Update:
Above answer will still require you to subscribe click event for each button. If you don't want that then have a look at following approach;
You could use (ClickTransparentButton or) disable (Enabled=false) all these buttons and add click event on parent Form. Once you get click event you can get button which was clicked as follows;
private void Form1_Click(object sender, EventArgs e)
{
var p = PointToClient(Cursor.Position);
var control = GetChildAtPoint(p);
if(control is Button)
{
var buttonText = ((Button)control).Text;
//Query using buttonText
}
}
But this has few disadvantages such as, you will not be able to operate these buttons using keyboard.
and more...
Create some function as buttons click handler:
private void buttonClickHandler(object sender, EventArgs e)
{
string buttonName = (sender as Button).Text;
}
2A. Connect Click event of every button to this handler.
2B. To automate connection of button click handler use something like that:
private void connectButtonsHandlers()
{
foreach(var c in this.Controls)
{
if(c is Button)
{
(c as Button).Click += buttonClickHandler;
}
}
}
Add this code to form constructor to perform connection at program start.

ComboBox show dropdown menu on text selection

I want to show the list of items in a combo box when the user selects the text. I have a touch screen application and it's very difficult to hit the dropdown arrow so I figure I'd show the menu when the text is selected which is often what gets touched. I'm using VS 2008. and suggestions for a touch friendly numeric up down solution in VS2008?
You could use the ComboBox.Click event handler and the ComboBox.DroppedDown property and do something like this:
private void ComboBox1_Click(System.Object sender, System.EventArgs e)
{
ComboBox1.DroppedDown = true;
}
You could also use the same event handler for a numericUpDown and use the mouseposition as well as the position and height of the NumericUpDown to get whether or not the click was above or below the halfway-line of the control by doing something like this (not sure if my math here is perfect, but it worked when I tested it):
if ((MousePosition.Y - this.PointToScreen(NumericUpDown1.Location).Y < NumericUpDown1.Height / 2))
{
NumericUpDown1.Value += 1;
}
else
{
NumericUpDown1.Value -= 1;
}
HTH
I was working on a similar situation. We wanted to make the text area behave the same as the button on the right. (IE the user clicks and gets the drop down box)
davidsbro is similar to what I ended up doing, but we wanted it to close if they clicked again, so the value became dropDown.DroppedDown = !dropDown.DroppedDown;.
The issue with this is that if the user clicks the right button of the drop down box, the dialog box opens, then calls the onClick event.
I solved this situation by tracking the original state via the onmouseover event. If the value has changed, we have to assume that the button on the select box handled the click already.
private bool cbDropDownState = false;
private void dropDown_MouseEnter(object sender, EventArgs e)
{
cbDropDownState = dropDown.DroppedDown;
}
private void dropDown_Click(object sender, EventArgs e)
{
if (dropDown.DroppedDown == cbDropDownState )
dropDown.DroppedDown = !dropDown.DroppedDown;
}

After F1 was pressed help is not displayed

I do not understand why i did not get the help message after pressing the F1 key. When on windows form i got for instance one button and it has the focus the message is displayed as expected (after pressing F1) but when i got an empty form this is not happening. I suppose that an empty form will have by default focus set on it. ( i read that this event will be raised after pressing F1 for the control which got the focus)
Is this the right behavior, or i am missing something about the "HelpRequested" event on an empty form ? Is this the right way to raise the event based on focus or it could be configured to be raised also on another event (something like onMouseOver) ? May i create my own event and raise it ? (i do not want to add a special button only for help, for example press this button and display the help, help should be displayed only after F1 was pressed).
This is the code:
private void Form1_Load(object sender, EventArgs e)
{
Form1.ActiveForm.HelpRequested += new HelpEventHandler(helpReq);
//button1.HelpRequested += new HelpEventHandler(helpReq);
}
private void helpReq(object sender, HelpEventArgs hlpevent)
{
MessageBox.Show(((Control)sender).Text);
}
using Form1.ActiveForm, is not recommended. Change it to this
there is no Text property associated with Control. Do you mean Tag?
after performing the help event, you should set the HelpEventArgs.Handled to true
instead of using events, you can just override OnHelpRequested in your form.
I would do someething like this:
protected override void OnHelpRequested(object sender, HelpEventArgs e)
{
MessageBox.Show((Control) sender).Tag);
e.Handled = true;
base.OnHelpRequested(sender, e);
}

How can I keep multiple controls in focus?

I have a tree view on the left side. Selecting a node displays relevant information in a form on the right side.
Would I be able to keep the tree and any one control (textbox, combobox, checkbox) on the right in focus at the same time? This will enable a user to select a field, make a change, select another node, and without having to go back and select the same field again, just type and change the value of the same field.
Thanx.
EDIT
I suppose one could implement such behaviour manually:
private Control __cFocus;
private void {anyControl}_Focus(object sender, EventArgs e)
{
__cFocus = (Control)sender;
}
private void treeView1_AfterSelect(object sender, EventArgs e)
{
__cFocus.Focus();
}
I was just wondering if there exists an automatic / more elegant solution
EDIT 2
Ok, so it seems I'll have to implement it manually. Manual implementation it is then. However, now there seem to be another problem; not sure if I should ask this as a separate question.
When selecting a node the textbox gains focus as intended, but only when using the keyboard. It doesn't work when selecting a node with the mouse. First I thought that it might be a mouse event that's interfering, but stepping revealed that the MouseUp event fired first and then the AfterSelect event which sets the focus, so I don't think it's interfering. The textbox's Enter event is also fired, but for some reason it loses focus again to the tree.
Thanx
no, you cannot keep two controls in focus at the same time. But what you can do is set the focus to the target control in the treeview AfterSelect event
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
textBox1.Focus();
textBox1.SelectAll();
}
then in your textbox leave, save the changes, like so:
private void textBox1_Leave(object sender, EventArgs e)
{
//save changes here
}
this way, everytime you select an item in the treeview, check your textbox for change and save as needed, then you will refocus on the textbox for your next edit
There only can be one element having the focus!
But I have an idea for you that might solve your problem. Assuming you have a window with a TreeView and a TextBox. Set the HideSelection property of the TreeView to false and subscribe the AfterSelect event (like edeperson already answered) like this:
private void OnTreeViewAfterSelect(object sender, TreeViewEventArgs e)
{
textBox1.Text = e.Node.Text;
textBox1.Focus();
}
Then subscribe the KeyDown event of the TextBox and do following in the event method:
private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down))
{
treeView1.Focus();
SendKeys.Send(e.KeyCode == Keys.Up ? "{UP}" : "{DOWN}");
}
}
At last subscribe the Leave event of the TextBox and do following in the event method:
private void OnTextBoxLeave(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null)
{
treeView1.SelectedNode.Text = textBox1.Text;
}
}
And, voilá it should work like you expected it...
If you want to focus on it , you can use usercontrol. you can put your textbox on usercontrol and set focus of this textbox on usercontrol using set properties on treeview select.
No you may not, only one control may be in focus at any given time.
See Moonlight's comment for one way to achieve the behavior that you seek.

Problem with button when text entered into the textbox

I am trying to make the save button visible when text is entered into the text box by using the following code:
if (tbName.TextModified == true)
{
btnCTimetablesOk.Visible = true;
}
else
{
btnCTimetablesOk.Visible = false;
}
but it gives error at tbname.textmodified
is there any other way to visible the button when we enter the text in text box
this is error i am getting "the event textbox.textmodified can only appear on the left hand side of += or -="
Try using the textbox's Enter and Leave events to show/hide your button:
private void textBox1_Enter(object sender, System.EventArgs e)
{
btnCTimetablesOk.Visible = true;
}
private void textBox1_Leave(object sender, System.EventArgs e)
{
btnCTimetablesOk.Visible = false;
}
Then modify your textbox to use these new methods.
If I'm reading your text correctly, you want the save button to be visible when the textbox has text in it and invisible when the text box is blank. If that's the case, you can use the Leave event (which occurs when the textbox loses focus) and a simple if statement:
private void textBox1_Leave(object sender, System.EventArgs e)
{
if(textBox1.Text != "")
btnCTimetablesOk.Visible = true;
else
btnCTimetablesOk.Visible = false;
}
You can also put this conditional block in any other methods kicked off by events that change the text of the box.
Also, you might want to consider using Enabled instead of Visible, it'll leave the button on the form but will gray out the text and clicking will do nothing.
I'm going to take a stab in the dark here and assume that the button is related to the textbox and you probably want someone to be able to type something in the textbox then click the button. You probably don't want the user to have to type something, then tab out or click somewhere else to make the button visible then click the button.
tbName_TextChanged(object sender, EventArgs e)
{
btnCTimetablesOk.Visible = !String.IsNullOrEmpty(tbName.Text)
}
Btw you're getting that error because TextModified isn't a boolean property, it's an event, like TextChanged or Leave or Enter. You can assign an event handler to it but you can't just check it like that.
As an aside I personally hate systems hungarian for winforms controls. I'd much rather have a timetablesOkButton than a btnCTimeablesOK button. That way if you also have a timetablesNameTextBox you can see at a glance that the button and the textbox match. Of course it may not be up to you.

Categories

Resources