如何使用C#windowapplication中的datagridview内的文本框执行事件 [英] How to perform an event with textbox which is inside a datagridview in C# windowapplication

查看:52
本文介绍了如何使用C#windowapplication中的datagridview内的文本框执行事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个dataGridView。

其中有两个文本框。一个用于产品和另一个是价格。

我想用文本框(产品)执行一个事件,这样我就可以在下一个单元格中找到并显示输入产品的价值(价格)。



我尝试了什么:



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:

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+"'";
.
.
.
.

   }
}

推荐答案

如果您只是使用标准数据网格视图,则可以使用 CellValueChanged 事件:

If you just use a standard datagridview you can use the CellValueChanged event:
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;
		}
	}
}


会员11827207写道:

如果我能够使事件发生火灾,我可以检查输入的值是否为数字。

即使我可以从数据库中获取一些相应的数据。
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.

谢谢你的澄清;你应该在第一时间详细解释。



不幸的是,你正式接受完全糟糕的解决方案1.从来没有做过这样的事情,首先,永远不要做愚蠢的事情喜欢硬编码ColumnText等。此外,它根本没有提供任何解决方案。



您可以做两件事:1)捕获就地编辑控件的输入事件并过滤掉所有输入除数字和退格之外的字符(解释为代码为8的字符); 2)当编辑模式结束时,验证所有输入的文本。在我的解决方案中,您需要处理网格视图的三个事件以及可以从事件 DataGridView中提取的就地控件的 KeyPress 事件。 EditingControlShowing 。在我的代码示例中,事件 DataGridView.CellBeginEdit 专门用于通过在 currentRow,currentColumn 。你我需要它只是因为你想要对所有要编辑的单元格应用验证过滤,而只是对其中一些单元格应用。可以通过列或列和行来区分单元格。



下面显示的代码可以添加到表单构造函数末尾的任何位置。请注意,我将 editControl currentRow 声明为 currentColumn 作为本地变量;通过闭包机制从事件处理程序访问(关闭(计算机编程) [ ^ ])。



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)[^]).

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



在这里,你有两个添加两个方法: NeedsFiltering(int,int)用于验证有问题的单元格与整数编辑任务相关,以及你的验证方法编辑的单元格内容, ValidateCell(int,int)



验证算法的架构:



首先,你通过其牛/列索引得到一个单元格;对于单元格,使用它的属性提取其值,将其强制转换为字符串并验证字符串值。

对于数字验证,使用 int.TryParse (或您需要的整数类型)。尽管您已确保用户仅输入数字,但仍可能无法成功解析。比方说,没有数字或太多数字。因此,此方法应对有效整数返回true。在这种情况下,在第二个参数中返回整数值,您可以检查整数值是否有效。



解决方案中有一个非常微妙的点:添加过滤事件处理程序时,网格视图不会每次都创建就地编辑器的新实例。第二次,它可以提供以前创建的控件实例,它适用于新的编辑会话;这才是真正发生的事。这就是为什么我通过与变量 editControl 进行比较来检查它是与以前相同的编辑器。如果没有这个检查,它将创建一个非常潜意识的内存泄漏,因为同一个事件处理程序将一次又一次地添加到同一个控件。这是一个罕见的情况,当一个小错误可以在托管内存中创建内存泄漏。 (许多人认为管理内存泄漏是不可能的,但事实并非如此。)



我的解决方案经过全面测试,请确保。






现在,关于Richard Deeming在他对这个问题的评论中提出的SQL注入问题。他是完全正确的。



从一开始你的方法就错了。通过串联从UI获取的字符串组成的查询。不仅重复的字符串连接是低效的(因为字符串是不可变的;我是否必须解释为什么它会使重复连接变坏?),但是有更重要的问题:它打开了通向良好的大门已知的漏洞称为 SQL注入



这是它的工作原理: http://xkcd.com/327



你明白了吗?从控件中获取的字符串可以是任何东西,包括......一段SQL代码。



怎么办?只需阅读有关此问题和主要补救措施:参数化语句 http://en.wikipedia.org/ wiki / SQL_injection



使用ADO.NET,使用:http://msdn.microsoft.com/en-us/library/ff648339.aspx



请参阅我过去的答案有更多细节:

在com.ExecuteNonQuery中更新EROR( );

嗨名字没有显示在名称中?



-SA


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.




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


这篇关于如何使用C#windowapplication中的datagridview内的文本框执行事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆