I am using a windows form and within the form i have a user control with two labels, one that has a message ENTER AMOUNT and the other where I am putting the values typed by the user (like when you go to an ATM) it starts showing the number .. it works fine if i dont have any other controls on the user control.. but the moment i add a button it does not work, it wont start showing the numbers as I use my numeric key pad.. but if i remove whatever button i added it works again... Here is my user control code.
public partial class OperationAmount : UserControl
{
public OperationAmount()
{
InitializeComponent();
}
private int _inputNumber = 0;
private void OperationAmount_Load(object sender, EventArgs e)
{
}
private void Form_KeyAmountPressed(object sender, KeyPressEventArgs e)
{
if (!Char.IsNumber(e.KeyChar))
{
return;
}
else if (lblOperationAmount.Text.Length > 9)
{
return;
}
else
{
_inputNumber = 10 * _inputNumber + Int32.Parse(e.KeyChar.ToString());
ReformatOutput();
}
}
private void ReformatOutput()
{
lblOperationAmount.Text = String.Format("{0:0.00}", (double)_inputNumber / 100.0);
}
}
Probably the new control steals the keypresses from your Form_KeyAmountPressed method because now it has the focus and receive the event KeyPress.
A simple workaround would be to add the method Form_KeyAmountPressed also at the KeyPress event of the button. Try also to set the TabStop property of the button to false. (not sure if this has any effect when the button is the only control that can get focus on your user control).
Related
I have a ContextMenuStrip with a ToolStripButtonMenu "Print".
A MDI child form is open containing a DataGridView. I am doing a validation to an editable column "Copies" in that grid. I don't want the user to input letters for example. The validation is working fine when leaving the cell but if I am clicking on a control such as the "Print" button, the validation is not caused.
The following screen shot shows how I can click on the "Print" button while the Copies cell contains letters:
// The code for the cell validation
private void QuantitiesDataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
if (e.ColumnIndex == QuantitiesDataGridView.Columns[COL_COPIES].Index)
{
QuantitiesDataGridView.Rows[e.RowIndex].ErrorText = "";
int enteredValue;
if (!int.TryParse(e.FormattedValue.ToString(), out enteredValue) || enteredValue < 1)
{
e.Cancel = true;
QuantitiesDataGridView.Rows[e.RowIndex].ErrorText = "Invalid number of copies";
}
}
}
I was looking for a property of the ToolStripButtonMenu such as CauseValidation but there is not such one.
Is there a way to trigger the validation when clicking on one of the ToolStripButtonMenu so the Print button will not be triggered until the Copies value is valid?
In your ToolStripButton's Click method, try calling the active form's ValidateChildren function:
private void toolStripButton1_Click(object sender, EventArgs e) {
if (this.ActiveMdiChild.ValidateChildren()) {
// do your processing ...
}
}
I am trying to have a C# program running in the background on Windows that will print "Hello!" after seeing that the user has clicked his or her mouse 10 times. But not just in the console window, anywhere on the screen.
The following event handler for click-tracking is from msdn.microsoft.com:
private void OnMouseDownClickCount(object sender, MouseButtonEventArgs e) {
// Checks the number of clicks.
if (e.ClickCount == 1) {
// Single Click occurred.
lblClickCount.Content = "Single Click";
}
if (e.ClickCount == 2) {
// Double Click occurred.
lblClickCount.Content = "Double Click";
}
if (e.ClickCount >= 3) {
// Triple Click occurred.
lblClickCount.Content = "Triple Click";
}
}
But, I'm not sure how to actually use this. When I add this function anywhere, the MouseButtonEventArgs type is undefined.
What "using" statements do I need? How do I actually get this code to run properly -- do I call it once from main? What do I do to call it?
EDIT: Here is a picture showing Visual Studio not understanding MouseButtonEventArgs:
Initially You have to select the form and go to properties, Here you have to go events area and there is MouseClick event. Click that Mouse click. Go to Code behind window. there is the click event generated automatically. In that Form_MouseClick event you can count the number of clicks.
Initially declare a variable
int count = 0;
In method
Private void Form_MouseClick(object sender, MouseEventArgs e)
{
count++;
//add lable which will displays the count value
label.Text=count.ToString();
}
I think which will helps to count the clicks in the form.
I'm not entirely sure what you're trying to accomplish but..
To track user clicks I hooked up the "MouseDown" event on a form in a Windows Forms applications.
From there I check click counts in the event handler.
using System;
using System.Windows.Forms;
namespace WindowsFormsApplicationTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent( );
this.MouseDown += Form1_MouseDown;
}
private void Form1_MouseDown( object sender, MouseEventArgs e )
{
// Count clicks
}
}
}
I'm making a windows forms application and on startup of the application the cursor is in the wrong text box.
I've tried searching some other questions online, but nothing seems to work for me.
I've tried inputBox.Focus(); bot after the Initialize Component, I've also tried this in my input box method, and I've tried inputBox.Select(); in a few places as well. It doesn't seem to make a difference.
I've also seen that you can set the tab index of the text box to be zero, but unfortunately I don't understand. I can't find this option anywhere in visual studio. I figured this would be in the properties for the text box in the designer. Am I looking in the wrong place? Or should I be looking for a different solution?
Here's my code:
namespace Project_9
{
public partial class Form1 : Form
{
const int MAX = 10;
Bowling objectRef;
public Form1()
{
InitializeComponent();
objectRef = new Bowling(10);
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
{
MessageBox.Show("Jonathan Spalding\nCS1400\nProject 9");
}
private void inputBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
string text = inputBox.Text;
if (text == "")
{
highScoreBox.Text = objectRef.GetHighScorePlayer() + ": " + string.Format("{0:d}", objectRef.GetHighScore());
lowScoreBox.Text = objectRef.GetLowScorePlayer() + ": " + string.Format("{0:d}", objectRef.GetLowScore());
averageScoreBox.Text = string.Format("{0:f2}", objectRef.GetAverageScore());
}
else
{
inputBox.Clear();
objectRef.AddPlayer(text);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
inputBox.Focus();
}
}
}
Select the textbox. In the properties window find TabIndex (If you can not find it, sort the properties in A-Z as in the small red rectangle.
Make sure:
1. that the TabIndex is the smallest value comparing to the other controls (as in my example two comboboxes each one has a TabIndex value)
2. The TabStop value is True.
In the Load event
ActiveControl = inputBox;
You can set the TabIndex property to a value bigger than 0. The control wih the least value will focus on startup.
You can then set the TabIndex on the other controls so that when you press the tab key, the next control (with higher TabIndex) will get the focus.
In your form constructor you can use:
public Form1()
{
InitializeComponent();
inputBox.Focus();
}
Or
public Form1()
{
InitializeComponent();
inputBox.Focus();
inputBox.Select();
}
I think the best way is to set TabIndex by clicking with mouse on controls. Just go to view menu and then to TabIndexOrder menu option.
Then you can set TabIndex order just by clicking on the TabIndex represented on your form just the way you want to.
When you finish just select TabIndexOrder menu option again to exit helper.
I created a user control that functions as a keyboard. I arranged the buttons in the control in the exact same manner as a keyboard, and set (ControlStyles.Selectable, false). This allows the focus to stay in a textbox that the user selected on the parent form. I also set the style of the user control to not be selectable. Everything works great when the user presses the buttons, but when the user control gets clicked, it steals the focus away from the textbox. Here is my code:
public partial class TouchKeyboard : UserControl
{
public TouchKeyboard()
{
InitializeComponent();
SetStyle(ControlStyles.Selectable, false);
}
private void TouchKeyboard_Load(object sender, EventArgs e)
{
foreach (var button in this.Controls.OfType<CustomControls.CustomButton>())
{
button.Click += new EventHandler(this.ButtonClick);
}
}
private void ButtonClick(object sender, EventArgs e)
{
var button = sender as CustomControls.CustomButton;
if (button.Name == "btnSpace")
{
SendKeys.Send(" ");
}
else
{
SendKeys.Send("{" + button.Text + "}");
}
}
}
Why would my user control steal focus when ControlStyles.Selectable is set to false?
After a few days of screwing with it, I finally figured it out. Since panels don't steal focus, I docked a panel in the User Control and placed my buttons inside it. That fixed the problem.
To make sure that the user name input is valid, I added such callback method to do the verification:
Regex UserNameRE = new Regex(#"^[a-zA-Z]\w*$");
//being called when input box is not focused any more
private void UserNameInput_Leave(object sender, EventArgs e)
{
//pop up a warning when user name input is invalid
if (!UserNameRE.IsMatch(UserNameInput.Text))
{
MessageBox.Show("Invalid User Name!");
this.UserNameInput.Text = "";
this.UserNameInput.Focus();
}
}
The method will be called when user finished their inputting(the method is bounded with the event-"leaving the input box"). It works when user left a invalid User_Name and begin to enter a password.
But it also works when user click another tab, e.g. the Register tab. I don't want this happen. Because the user obviously don't wanna login anymore if he clicks "Register" tab, and my C# app shouldnot pop up a warning box and force them inputting a valid user name again.
How can the C# tell the difference of such 2 situations? It should be easy if I know which object is being clicked.
You will have source of event in object sender in UserNameInput_Leave event.
private void UserNameInput_Leave(object sender, EventArgs e)
{
//sender is source of event here
}
Here's an option:
private void UserNameInput_Leave(object sender, EventArgs e)
{
if (sender.GetType() != typeof(TextBox))
{
return;
}
TextBox tBox = (TextBox)sender;
//pop up a warning when user name input is invalid
if (!UserNameRE.IsMatch(UserNameInput.Text) && tBox.Name == UserNameInput.Name)
{
MessageBox.Show("Invalid User Name!");
this.UserNameInput.Text = "";
this.UserNameInput.Focus();
}
}
I am not sure if there's a right solution for this particular scenario here.
When you add a handler to validate your control on mouse leave, definitely it will be executed first regardless you clicked on another control within the tab or another tab itself.
This normal flow can't be ignored easily. It must be possible by hanlding the message loop yourself but the event based flow, first leave focus, and selected index change (selecting) event will be fired. I would suggest you not to disturb the flow as the validation is client side and pretty fast. Instead of messagebox, I would recommend you to use ErrorProvider and attach to the control whenever required. Also messagebox is quite disturbing and as per your code, you're forcefully making it focus to the textbox again.
How about the following code?
public partial class Form1 : Form
{
ErrorProvider errorProvider = new ErrorProvider();
public Form1()
{
InitializeComponent();
textBox1.Validating += new CancelEventHandler(textBox1_Validating);
}
private void textBox1_Leave(object sender, EventArgs e)
{
textBox1.CausesValidation = true;
}
void textBox1_Validating(object sender, CancelEventArgs e)
{
Regex UserNameRE = new Regex(#"^[a-zA-Z]\w*$");
if (!UserNameRE.IsMatch(textBox1.Text))
{
errorProvider.SetError(this.textBox1, "Invalid username");
}
}
}