Click here to Skip to main content
15,949,686 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have a dataGridView.
Inside it, there are two textboxes. one for product & another for price.
I want to perform an event with textbox (for product) so that I can find and show the value of input product in the next cell (for price).

What I have tried:

C#
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
   if (dataGridView1.CurrentCell.ColumnIndex == 1)
   {
         
     TextBox txtProduct = e.Control as TextBox;
     cmd.CommandText = "Select * from tbl_product where product='"+txtProduct.Text+"'";
.
.
.
.

   }
}
Posted
Updated 5-May-16 4:26am
v2
Comments
Richard MacCutchan 4-May-16 9:34am    
You need to add an event handler for that column of the DatasGridView, that fires when the data is complete. Tyy the Leave event, or maybe the end of edit in the TextBox.
Sergey Alexandrovich Kryukov 4-May-16 10:05am    
What event, exactly?
—SA
Bhola Ram Sahu 4-May-16 23:18pm    
any type of event like textbox_leave, textbox_changed etc.
Sergey Alexandrovich Kryukov 5-May-16 0:54am    
Probably you want to capture something that indicates that the user completes entering of the cell data, right?
—SA
Bhola Ram Sahu 5-May-16 6:18am    
right.

if I am able to make an event fire, I can check if the entered value is number.
Even I can fetch some corresponding data from database.

If you just use a standard datagridview you can use the CellValueChanged event:
C#
private void DataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
	if (e.RowIndex >= 0)
	{
		DateTime newDate;

		switch (this.DataGridView1.Columns[e.ColumnIndex].Name)
		{
			case "ColumnText":
				string newText = this.DataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
				break;
			case "ColumnCombo":
				string newPriority = this.DataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
				break;
			case "ColumnDate":
				DateTime.TryParse(this.DataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString(), out newDate);
				break;
		}
	}
}
 
Share this answer
 
Comments
Bhola Ram Sahu 6-May-16 9:01am    
Thanks a lot...
its working..
Thanks again...
amcompe 14-Apr-22 16:36pm    
Thanks!
Member 11827207 wrote:
if I am able to make an event fire, I can check if the entered value is number.
Even I can fetch some corresponding data from database.
Thank you for the clarification; you should have explained that in detail in first place.

Unfortunately, you formally accepted totally bad Solution 1. Never do such things, first of all, never do stupid things like hard-coding "ColumnText" and the like. Besides, it does not provided any solution at all.

You can do two things: 1) capture the entering event of the in-place editing control and filter out all entered characters except digits and backspace (which is interpreted as character with code point 8); 2) when editing mode is ended, validate all entered text. In my solution, you need to handle three events of you grid view plus KeyPress event of the in-place control you can extract from the event DataGridView.EditingControlShowing. In my code sample, the event DataGridView.CellBeginEdit is used exclusively to locate the currently editing cell via storing coordinates in currentRow, currentColumn. You my need it just because you want to apply the filtering of validation not for all cells to be edited, but only to some of them. The cells can be discriminated by columns, or both column and row.

The code shown below could be added anywhere at the end of the form constructor. Note that I declared editControl, currentRow as currentColumn as local variable; the are accessed from the event handler via the closure mechanism (Closure (computer programming)[^]).

C#
Control editControl = null;
int currentRow, currentColumn;
            
myGridView.EditingControlShowing += (sender, eventInstance) => {
    if (!NeedsFiltering(currentRow, currentColumn)) return           
    if (eventInstance.Control != editControl) {
        editControl = eventInstance.Control; 
        editControl.KeyPress += (editorSender, editorEvent) => {
            editorEvent.Handled = // filter out unwanted characters:
                !(char.IsDigit(editorEvent.KeyChar)
                  || editorEvent.KeyChar == (char)8);
        }; //KeyPress handler
    } //if
}; //myGridView.EditingControlShowing

myGridView.CellBeginEdit += (sender, eventInstance) => {
    currentColumn = eventInstance.ColumnIndex;
    currentRow = eventInstance.RowIndex;
}; //myGridView.CellBeginEdit

myGridView.CellEndEdit += (sender, eventInstance) => {
    ValidateCell(eventInstance.ColumnIndex, eventInstance.RowIndex);
    //whatever it is
}; //myGridView.CellEndEdit

Here, you have two add two methods: NeedsFiltering(int, int) used to validate that the cell in question is relevant to the task of integer editing, and your validation method of the just edited cell content, ValidateCell(int, int).

The schema of validation algorithm:

First, you get a cell by its cow/column indices; for the cell, extract its value by using it's property Value, typecast it to string and validate string value.
For numeric validation, you use int.TryParse (or the integer type you need). Despite the fact that you already made sure the user entered only digits, it still may not parse successfully. Say, no digits or too many digits. So, this method should return true for valid integer. In this cases, integer value is returned in the second parameter, and you can check up if the integer value is valid.

There is one quite delicate point in the solution: when you add the filtering event handler, the grid view does not create new instance of the in-place editor each time. On second time, it can provide previously created control instance, it it is suitable for new editing session; this is what really happened. That's why I check up that it's the "same editor as before" via comparison with the variable editControl. If not this check, it would create a very subliminal memory leak, because the same event handler would be added to the same control again and again. This is one of the rare cases when a small mistake can create a memory leak in managed memory. (Many think that managed memory leak is impossible, but this is not true.)

My solution is fully tested, be sure about that.

[EDIT]

Now, about the SQL injection issue raised by Richard Deeming in his comments to the question. He is perfectly right.

Your approach is wrong from the very beginning. The query composed by concatenation with strings taken from UI. Not only repeated string concatenation is inefficient (because strings are immutable; do I have to explain why it makes repeated concatenation bad?), but there is way more important issue: it opens the doors to a well-known exploit called SQL injection.

This is how it works: http://xkcd.com/327.

Are you getting the idea? The string taken from a control can be anything, including… a fragment of SQL code.

What to do? Just read about this problem and the main remedy: parametrized statements: http://en.wikipedia.org/wiki/SQL_injection.

With ADO.NET, use this: http://msdn.microsoft.com/en-us/library/ff648339.aspx.

Please see my past answers for some more detail:
EROR IN UPATE in com.ExecuteNonQuery();,
hi name is not displaying in name?.

—SA
 
Share this answer
 
v5
Comments
Bhola Ram Sahu 6-May-16 9:02am    
Its nice to have another solution.
Yeah, your solution is better.. But that was also fine. Its good to say that I am following your answer...
Thank you sooooooo muchhhhhh.
Sergey Alexandrovich Kryukov 6-May-16 9:22am    
I'm very glad; thank you for the note.

If you mean Solution 1 by "that", it is totally unacceptable as formulated. It could be "fine" to use it just for a general idea; it if merely about the guess what event to handle.
The problem is the whole idea of writing the case statement and hard-coded options. This is totally unmaintainable.
Please see: https://en.wikipedia.org/wiki/Anti-pattern, https://en.wikipedia.org/wiki/Magic_string#Magic_strings_in_code.

Good luck, call again.

—SA
Bhola Ram Sahu 10-May-16 3:18am    
Its your amazing solution which made me post a reply again.

Your solution is very nice and absolutely correct and useful for every situation.

thanks again.

You are amazing.
:-)
Sergey Alexandrovich Kryukov 10-May-16 8:30am    
My pleasure.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900