I have next issue, I am working on small c#-wpf application,
and on load I am disabling button which is ussualy used to do some action on click, and it looks like this:
public MainWindow()
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
if (String.IsNullOrEmpty(password.Password))
{
btnActivate.IsEnabled=false;
}
}
and somewhere I am checking my password field, for example:
private void password_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Enter))
{
if (password.Password == "drag0n")
{
btnActivate.IsEnabled = true;
}
else
{
btnActivate.IsEnabled = false;
}
}
}
And my problem is next, when user enter "drag0n" and press enter, button should be just enabled, but its not only enabled, its calling automatic his event _Click, I don't know why does that happening, because in that case, if my button is just enabled event _Click is also called, and if user clicks on that button, event is called again, so actually my event onclick is called twice.
My question is how can I stop calling my Click event if I set IsEnabled=true. When I set IsEnabled=true I just want it to be enabled for pressing and I don't want execute event _Click.
I want to execute event _Click only when my button is pressed as it should work and not on IsEnabled=true.
Thanks guys,
Cheers
On click event occurs when you press Enter key, because this button is the default control in a form.
If you don't want click event on Enter key, you should either make this button not default or not process Enter key pressing in your button click (e.Handled = true -> when Enter is pressed).
Or try to change your code:
private void password_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key.Equals(Key.Enter))
{
if (password.Password == "drag0n")
{
e.Handled = true; // add this line
btnActivate.IsEnabled = true;
}
else
{
btnActivate.IsEnabled = false;
}
}
}
Related
I would like to help with my new clicker game that I'm working on and I've stumbled upon a problem with adding a value to the "playerPoints" which is from launch 0. You need to click a button which is called "button_click" which will add +1 (++) to your "playerPoints". But there is a bug when you click the button and then hold the enter button it will act like a little auto clicker which I don't want. Is there a way how to prevent the enter key to add value when it is pressed or held down? Thanks in exchange.
int playerPoints = 0;
public void button_click_Click(object sender, EventArgs e) // main click button
{
playerPoints++;
label_points.Text = playerPoints.ToString() + " BITS";
}
The problem has been solved by an great idea by: Dan Byström
If you don't want to make the button respond to keys like enter.
Use a simple image or label and link that function to the image_click or label_click
again thanks alot guys!
When you click on the subject Button, it becomes the form's ActiveControl. As part of the form's internal processing in setting the ActiveControl, the Form.UpdateDefaultButton Method is called.
Remarks
The UpdateDefaultButton method determines which button on the form raises its Click event when the user presses ENTER, according to the following priority:
To avoid having the subject button becoming the Default Button, override the form's UpdateDefaultButton method with something like this:
protected override void UpdateDefaultButton()
{
if (ActiveControl == button_click)
{
return;
}
else
{
base.UpdateDefaultButton();
}
}
Hook the KeyDown event instead of the Click event.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.keydown
Button.KeyDown += Button_KeyDown;
// Handle the KeyDown event
private void Button_KeyDown(object sender, KeyEventArgs e)
{
//increment your counter
}
I have a simple Winform example that demonstrates what happens.
There is a GroupBox with two RadioButtons. The two buttons share a validating event handler. Also on the form is a Button that does nothing. No events are connected. Finally there is a CheckBox that controls the state of a passing validation. Checked it passes and unchecked it fails.
When the program starts and the user clicks on either RadioButton the validating event does not fire. Then when I click on any control other than the current button the Validating Event fires. The NOP button gives me something to click besides the CheckBox.
In this test the CheckBox represents the status of passing the validation.
This will not work because once I uncheck the CheckBox and then click a radio button the focus is forever stuck. You can't get the focus to the CheckBox to change its state.
The reason is the Validating event is always called when the focus is leaving and not when the RadioButton is clicked. It sees that "valdating" fails and cancels the event.
This is obviously the wrong approach. What should I be doing to test at the time of the initial click? The Click event happens after the state has changed.
What event should I use so that I can test validation before changing the RadioButton state? Then I can leave the button and fix the issue before trying again.
This example is a simplified test that shows my dead end. My real world example is the two RadioButtons select one of two similar tables in a DataGridView. The two tables are related and I want them to be on the same TabPage. When the user selects the alternate table I want to do a validation/confirmation before switching away. If the confirmation fails I want to cancel the radio button.
// Validate is called when the radio button is clicked and when it leaves the box
using System.ComponentModel;
using System.Windows.Forms;
namespace ValidateRadioButton
{
public partial class Form1 : Form
{
int count;
public Form1()
{
InitializeComponent();
}
private void radiobutton_Validating(object sender, CancelEventArgs e)
{
if (sender is RadioButton) {
// If box not checked, cancel radioButton change
// This becomes a Hotel California test, once unchecked you
// can never leave the control
e.Cancel = !chkAllowChange.Checked;
}
count++;
//Display the number of times validating is called in the title bar
//Demonstrates when the event is called
Text = count.ToString();
}
}
}
I have reproduced your form in a test project and I think I see what is going on.
Setting the Checked property of CancelEventArgs to true will prevent whatever control set it from losing focus until input is "corrected". As you are aware, the Validating event is triggered whenever a control loses focus. The user becomes "stuck" as you say because the only way they can "correct" their input is to modify the check box, which they cannot get to because of the Validating event which fires on the radio button.
A solution which I came up with was moving the Validated event to the GroupBox, instead of the radio buttons:
private void groupBox_Validating(object sender, CancelEventArgs e)
{
if (sender is RadioButton)
{
e.Cancel = !checkBox1.Checked;
}
count++;
//Display the number of times validating is called in the title bar
//Demonstrates when the event is called
Text = count.ToString();
}
Be sure to remove the Validating event handler from the radio buttons.
For clarity, I have set my form up in this manner:
The result is now I cannot click the 'OK' until I have ticked the check box. I have preserved your Text = count.ToString() assignment so that you can see that the form now calls Validating only as it should.
I ended up using the CheckChanged and Click events for the RadioButtons.
I track the currently active RadioButton and do the validation in the CheckChanged event. Then in the Click event, if the validation failed I restore the previous active RadioButton. Otherwise we can continue to the purpose of the RadioButton.
This solution works for two or more RadioButtons in a group and it works when using the keyboard.
using System.ComponentModel;
using System.Windows.Forms;
namespace ValidateRadioButton
{
public partial class Form1 : Form
{
// RadioButton that is currently active
RadioButton ActiveRadioButton;
bool cancelingChange;
public Form1()
{
InitializeComponent();
activeRadioButton = this.radioButton1;
}
private void radioButton_CheckedChanged(object sender, System.EventArgs e)
{
// Each click fires two events
// One for the RadioButton loosing its check and the other that is gaining it
// We are interested in the one gaining it
if (sender is RadioButton) {
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked) {
// If this button is changing because of a canceled check
// do not validate
if (!cancelingChange) {
cancelingChange = !ValidateData();
if (!cancelingChange) {
// Mark this as the active value
activeRadioButton = radioButton;
}
}
}
}
}
private void radioButton_Click(object sender, System.EventArgs e)
{
// This is called after the RadioButton has changed
if (cancelingChange) {
// Check theRadioButton that was previously checked
activeRadioButton.Checked = true;
cancelingChange = false;
}
else {
// Do the thing the RadioButton should do
// If using separate events they all must start with the condition above.
this.Text = ((RadioButton)sender).Name;
}
}
/// <summary>
/// Validate state of data
/// </summary>
/// <returns></returns>
private bool ValidateData()
{
bool result = chkAllowChange.Checked;
if (!result) {
result = MessageBox.Show("Do you want to save your data?", "CheckBox unchecked", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation) == DialogResult.OK;
if (result) {
// This is where I would save the data
chkAllowChange.Checked = true;
}
}
return result;
}
}
}
I have a button2 which has a lot of code to execute when is clicked.
At some point, I need to wait until a boolean is set to true, and that boolean is made true when button 1 is pressed. (I can't press button 1 while button2's code is running).
I've searched, but all I found is with methods running async. How can I wait for button 1 to be pressed?
Here's a possible solution (may not be the most elegant):
public partial class Form1 : Form
{
// Variable to store whether button one has been clicked or not
private bool btnOneClicked = false;
// ..
private void btnOne_Click(object sender, EventArgs e)
{
// When button one is clicked, execute the code that needs to run before waiting for your second button to be clicked
LongCodeToExecuteFirst();
// Set your variable to true to say that button one has been clicked
btnOneClicked = true;
}
private void btnTwo_Click(object sender, EventArgs e)
{
// First check if button one has been clicked
if (btnOneClicked)
{
// If it has, execute the rest of the code that needed to be executed after button two was pressed
LongCodeToExecuteSecond();
// Reset our button one pressed variable to false
btnOneClicked = false;
}
}
private void LongCodeToExecuteFirst()
{
// Code to execute before button two is pressed
}
private void LongCodeToExecuteSecond()
{
// Code to execute after button two is pressed
}
}
I have a userControl(DT_Navigator). there is a button (btnNew) in it.
I wrote the click button event for it:
public void btnNew_Click(object sender, EventArgs e)
{
btnNew.Enabled = false;
}
I use the user control button in another project and wrote another click event for it:
public void btnNew_Click(object sender, EventArgs e)
{
btnNew.Enabled = false;
}
but, when I press the Enter key, just the first event that I defined in user control, executes. However I want both events to execute.
when I click on btnNew, both events trigger, but when I press Enter key, only one event triggers.
how can I fix the problem? Thanks...
Try this:
DT_Navigator.btnNew.Click += new EventHandler(DTnewItem);
I want my combobox's dropdown list to be shown with combobox enter event. That's easy just by adding cmb_box.DroppedDown = true; in the Enter event, i know but if the user opens the list by clicking the arrow button, the list pops up then closes itself. I tried adding
if (!cmb_box.DroppedDown) cmb_box.DroppedDown = true;
but didn't help. I even tried to define a global var to set it true on DropDown event and false on DropDownClosed event and check it in Enter event but that didn't work either. So i guess i need to detect if Enter event triggered by DropDown event in Enter method. Is that possible?
Better you can write like this
private void textBox4_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')//Enter Key
{
cmb_box.Focus();
cmb_box.DroppedDown = true;
}
}
textBox4 is the control before the combobox(cmb_box) control