Detect when the key pressed is the first char - c#

I've added a KeyPress event handler to my DataGridView. If user presses "=" in a Cell, this event fires. But the = key must be first char.
How can I detect whether the pressed key is the first char?
I used the code shown here for this. I've made a string variable, named meter. It keeps the last pressed key, so I can understand from the length of meter if it's the first char or not.
It is worked actually, but when user deletes the key then it gives the wrong result.
Is there anyone give me some advice? Maybe different solution?
// this keeps pressed key and makes string.
string meter = string.Empty;
void Control_KeyPress(object sender, KeyPressEventArgs e)
{
// if the first pressed "=" key. Then meter="=". So meter length=1
meter = meter +e.KeyChar.ToString();
if (meter.Length == 1)
{
//if user keypress "="
if (e.KeyChar == '=')
{
//do things
}
}
}

I find a solution. I explain how to solve for other users If they face the similar problem.
First of all thanx to #Jimi. He gave me the idea.
I added "cellTb" object that represents the cell textbox using "EditingControlShowing" event.So it allows me to detect text is "=" or not. Here is the codes.
DataGridViewCell currentCell;
TextBox cellTb; // this represents cell textbox
private void dgv_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.KeyUp += new KeyEventHandler(Control_KeyUp);
currentCell = this.dgv.CurrentCell;
cellTb = (TextBox)e.Control;
}
void Control_KeyUp(object sender, KeyEventArgs e) //
{
if (cellTb.Text == "=") // this is my check operations.
{
if (e.KeyCode == Keys.D0) //if user keyup "="
{
//do things
}
}
}
Edit: Explanation
#Harald Coppoolse.Actually it is my fault not telling exactly what I'm trying to do. I want to try something similar excel aplication. If the user press “=”, then he/she can selects columns then when press Enter the result will shown. But the problem is after the user pressed “=” then selecting another cell make cursor leaves the main cell. I asked question about that before. There is a link below. But what i asked is some diffucult to make possible. #JohnG.( commenter) advice me to use textbox control.
Handle select click event datagridview
Its seems sense. So i decided to used textbox. I added picture for easy understanding how i perform it.
For now it seems succeeded but i do not know which problems will be occur in the future.
I want to touch on the points you draw attention.
“What would happen if the operator keeps the equal sign down for a
while,”
I tried now it returns string like that“=====”. This is user problem.
“what if the operator selects several rows and presses the equal sign?
And what about copy-paste to paste the equal sign, or drag and drop?”
Actually i never think about this situations. But i ll try if conditions.
In a conclusion i ll change my codes according to your directions.
Thank you very much and your time.

I'm not sure if it is wise to react on KeyPress. What would happen if the operator keeps the equal sign down for a while, so that a KeyPress appears rapidly after each other, or what if the operator selects several rows and presses the equal sign?
And what about copy-paste to paste the equal sign, or drag and drop?
I think what you want is this:
Whenever the operator is editing DataGridViewTextBoxCell X of the DataGridView, and during editing the contents of the EditingControl of the cell X contains only the equal sign, I want to call procedure MyProcedure(DataGridViewCell cell)
(TODO: invent proper name for MyProcedure)
So you don't want this when the operator has finished editing the cell, you want this during cell editing.
For this you need access to the DataGridViewTextBoxEditingControl Class
This object is only available while the DataGridViewTextBoxCell class is in edit mode. You get access to the object just before the operator starts editing via event DataGridView.EditingControlShowing
Using visual studio designer:
this.dataGridView1.EditingControlShowing += this.OnEditingControlShowing);
In the event handler you subscribe to the TextChanged event of the editing control that is about to be shown
private void OnEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
e.Control.TextChanged += ShownEditingControl_TextChanged;
}
Now whenever the operator types something in the Cell's editing control, you get notified:
private void ShownEditingControl_TextChanged(object sender, EventArgs e)
{
DataGridViewTextBoxEditingControl shownEditingControl =
(DataGridViewTextBoxEditingControl)sender;
// Do what you want to do:
Debug.WriteLine(shownEditingControl.Text);
}
You can do what you want to do if the text contains only the equal sign, or if the text has several characters with the equal sign as first character.
if (shownEditingControl.Text == "="
{
// do what you want to do if the operator edited only the equal sign
// for example:
DataGridView dgv = shownEditingControl.EditingControlDataGridView;
DataGridViewCell cell = dgv.CurrentCell;
MyProcedure(cell);
}

Related

TextBox method for checking numerics in C#

I am creating a program that has a lot of user inputs. Most of the user inputs are going to be in TextBoxes that need to be only numeric entries.
Currently, I am just using a TextChanged method for getting values, which then make other buttons/checkboxes show/hide based on the entry.
I am wanting to create a method or implement some kind of utilization that checks when is being inputted into the boxes, to either prevent people from making incorrect inputs, to fix changes that they had made, or to create a messagebox that will tell them that their input is invalid.
I have two ways I am currently working with but they don't work with each other.
I have a parse method, that converts the input text into a Double but the problem I am running into, if they utilize the backspace button then re-enter their numbers, it will not recognize the input (which is needed to open/close other textboxes/checkboxes). This does work with the TextChanged method.
I have a regex set that utilizes the PreviewTextInput and KeyDown methods. This works pretty well with not allowing certain inputs but it doesn't work with the textchanged method (or at least I don't understand how to point to it).
I am in need of some guidance on how to create a viable method for checking inputs into textboxes that doesn't require my users to press a button for each entry (aka checking real-time).
I think this is what you are looking for.
Binding.Validation
For an Int it is as easy as just binding to an Int.
If you need to be able to increase/decrease the value via button use NumericUpDown or one of its subclass.
If you just need a textbox, you have to handle PreviewKeyDown() event. You need to manually check for valid/invalid keys pressed. When an invalid key is pressed, you set e.Handled = true; to prevent the key down event from tunneling down.
I really couldn't understand completely, but according to me you are trying to prevent a textbox to take invalid input and at the same time you want to use TextChanged method, so you can do like this:
<TextBox Name="txtAddNumber" TextChanged="txtAddLable_TextChanged" PreviewTextInput="txtAddNumber_PreviewTextInput" />
And txtAddNumber_PreviewTextInput method:
private void txtAddNumber_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
char c = Convert.ToChar(e.Text);
if (!Char.IsLetter(c))
e.Handled = false;
else
e.Handled = true;
base.OnPreviewTextInput(e);
}
And if you want to handle some error message kind of thing on the base of input you can do like this:
private void txtAddNumber_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
char c = Convert.ToChar(e.Text);
if (!Char.IsLetter(c))
{
// Put your Logic here according to requirement
e.Handled = false;
}
else
{
// Put your Logic here according to requirement
e.Handled = true;
}
base.OnPreviewTextInput(e);
}
And
e.Handled = false means input is numeric and e.Handled = true means input is non-numeric.
And your txtAddLable_TextChanged method will bw like:
private void txtAddLable_TextChanged(object sender, TextChangedEventArgs e)
{
// Logics here...
}

C# WPF backspace event?

I'm new to WPF and C# so what I'm asking is if there is a backspace event like TextChanged event for TextBoxes?
I made a small Library program with renting books and everything is viewed at a ListView.
What I currently did is that you can filter book names just by typing inside the textbox, so if you have 1000 books and you type the letter 'b' then you might have only 150 books starting with 'b'.
The problem is whenever i press backspace, I want it to previously restore it to what it was.
For example: typing "bob" and then deleted b, I get bo and now i want to present what every starts with "bo".
Now I get the idea. All I need is just another textChanged event. but something need to inform that the text was changed, and I need something better then
if (backspace key is pressed) { Invoke textChanged }
Thx guys!
Well, should i delete the post? maybe some one else will search it someday.
backspace is actually causing a TextChanged event automatically! damn. thx anyway!
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.keydown(v=vs.110).aspx
Here is a reference on the msdn site.
http://csharp.net-informations.com/gui/key-press-cs.htm
On a different site (easier to read) This though looks like it is for Win Forms.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
MessageBox.Show("Enter key pressed");
}
if (e.KeyChar == 13)
{
MessageBox.Show("Enter key pressed");
}
}
Looks like you need to create an event that fires on a key down, then get the value of that key. I think there is a Keys.Backspace but to know for sure let intellisense help you.

RadGridView Enter Key Issue

I have a winform application that contain a radgridview. Only one cell is set to enable editing. The remaining cells are read only. I have several radgridview event handle that perform different computation. When I'm editing a cell and hit the tab key it jump to the next cell(perfect). My problem is when I hit the "Enter" key, it throw a sort of infinite loop error. How can I disable the "Enter" key or change the behavior to mimic the tab key function? I try the below but it doesn't catch the "Enter" key action. I was reading that the enter key triggers functionality in our Grid (end edit, move to next row, etc.),
private void radGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.SuppressKeyPress = true;
}
}
I was able to solve the problem by re-coding my codes. I had two cell value that get updated on the CellValueChanged event. I move the updated code to the CellEditEnd event.

Deselect text in DataGridViewTextBoxCell after .CommitEdit(DataGridViewDataErrorContexts.Commit)

Sometimes while the user is typing text in a DataGridViewTextBox you want to enable or disable a control, depending on the value being typed. For instance enable a button after you typed a correct value
Microsoft showed the way in an article about how to create a DataGridViewButtonCell that can be disabled.
This is their trick (it can also be seen in other solutions)
Make sure you get the event DataGridView.CurrentCellDirtyStateChanged
Upon receipt of this event, commit the changes in the current cell by calling:
DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
This commit will lead to the event DataGridView.CellValueChanged
Make sure you get notified when this event is raised
In your OnCellValueChanged function, check the validity of the changed value and decide
whether to enable or disable the corresponding control (e.g. button).
This works fine, except that the CommitEdit makes that the text is selected while in OnCellValueChanged. So if you want to type 64, you get notified when you type 6 and later when you type 4. But because the 6 is selected you don't get 64, but the 6 is replaced by 4.
Somehow the code must deselect the 6 in OnCellValueChanged before interpreting the value.
The property DataGridView.Selected doesn't do the trick, it doesn't deselect the text, but it deselects the cell.
So: how to deselect the text in the selected cell?
I think you need something that when the user is typing some text into the current cell, you need to know the current text (even before committing it) to check if some button need to be disabled. So the following approach should work for you. You don't need commit any thing, just handle the TextChanged event of the current editing control, the editing control is exposed only in the EditingControlShowing event handler, here is the code:
//The EditingControlShowing event handler for your dataGridView1
private void dataGridView1_EditingControlShowing(object sender,
DataGridViewEditingControlShowingEventArgs e){
var control = e.Control as TextBox;
if(control != null &&
dataGridView1.CurrentCell.OwningColumn.Name == "Interested Column Name"){
control.TextChanged -= textChanged_Handler;
control.TextChanged += textChanged_Handler;
}
}
private void textChanged_Handler(object sender, EventArsg e){
var control = sender as Control;
if(control.Text == "interested value") {
//disable your button here
someButton.Enabled = false;
//do other stuff...
} else {
someButton.Enabled = true;
//do other stuff...
}
}
Note that the conditions I used above can be modified accordingly to your want, it's up to you.

How can I display the number of checked checkboxes in a textbox from a column in a datagridview?

I have a DataGridView with a CheckBox column in it. (This is an inventory system.) The check is used to move serial numbers of items from one location to another in our company.
I also have a textbox where, as of now, the employee enters the number of items he is moving, then checks the appropriate serial numbers, and moves the items.
I would like the number in the textbox to be generated depending on how many serial numbers are checked. Is it even possible? I've tried about a hundred different solutions at this point and they all either end in strange errors, or give me no results whatsoever.
Untested, but this should be close enough. I read an article or ten about this once when I was having the same issue. The trick is to commit the edit immediately when the box is clicked on, which will then trigger the CellValueChanged event. You can then pick up the count from there.
This should update the textbox as you check and uncheck the checkbox:
private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dgv.IsCurrentCellDirty && dgv.CurrentCell.OwningColumn.Name == "MyCheckColumn")
dgv.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1) //just a guard for the header row
return;
if (dgv.Columns[e.ColumnIndex].Name == "MyCheckColumn")
textBox.Text = dgv.Rows.Cast<DataGridViewRow>().Count(r => Convert.ToBoolean(r.Cells["MyCheckColumn"].Value)).ToString();
}
Hopefully the Linq works. If not, you'll have to do it the old-fashioned foreach way with a sum variable. I know the DataGridViewRowCollection can be finicky sometimes.

Categories

Resources