Checking a column value when updating a gridview asp.net - c#

I'm trying to do some error handling on a column to see if it's not equal to a certain word. I'm wondering though do i do this on the RowUpdating event or the RowUpdated event. I've been trying to do this in the rowupdating event and haven't had any luck so far. Here's the code.
TableCell cell = GridView1.Rows[e.RowIndex].Cells[3];
if(cell.Text == "hello")
{
e.Cancel = true;
}
lblError.Text = "hello" + cell.Text;
I assume the 3 after inside the brackets after .Cells is the column index that I want. If i use .Cells[1] it will show the primary key no in the label, but if I try 2 or 3 nothing seems to be getting placed inside the cell variable.
My table has four columns, ID, Name, Price, and CategoryID. Any help is appreciated.

If you are trying to get the input box values, you will have to find the control like:
GridViewRow row = GridView1.Rows[e.RowIndex];
string price = ((TextBox)(row.Cells[3].Controls[0])).Text;
You can also check against the e.NewValues.
And fyi: You will have to set the e.Cancel=true, if you want to cancel the event upon meeting certain condition(s).
Check RowUpdatingEvent ref.

Related

Getting values from user added row in DataGridView

I would like to get value from row after a user added some row.
I have seen this issue Getting user added row in DataGridView
I have tried different DataGridView events: UserAddedRow, RowsAdded, RowValidated, RowPrePaint and etc. Everything works wrong.
private void sheetDataGridView_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
Console.WriteLine(e.Row.Cells[0].Value);
}
Being specific, obviously the grids AllowUserToAddRow is set to true and the underlying data source allows the user to add new rows. This new row in the grid is always placed at the bottom of the grid with obviously “empty” cells. Below is a grid that shows this “new” row.
You state that you want to get the values of the data from a cell when the user “adds” some value into one of the cells in the “new row.” Specifically, from your posted code, it appears you want the data from the “new row” at cell zero (0).
This is doable, however as noted in the comments and your current dilemma, you need to be careful “which” events you use and more specifically, what to “DO” when the event fires, paying particular attention to “WHEN” the event fires.
Feel free to drop a DataGridView and a multiline TextBox onto a new winforms Form as show above. Then using the code below, it may help to follow what is described below.
First, to note is “WHEN” does the grids UserAddedRow event fire? If you move the selected cell to the new row OR if you click into a cell in the new row… nothing happens… the UserAddedRow event does NOT fire.
However, if the selected cell is a cell in the “new” row… AND the “user” types a single character into the cell… THEN the grids UserAddedRow fires. You should note some additional behavior.
One thing to notice is that as soon as the user types a character into the new row cell… the grid “ADDs” another “new” row.
Another important thing to note is that “when” this event fires, the user has ONLY typed a single character into the cell. If the user continues to type additional characters into that cell or moves to another cell in the “new” row and starts typing text… the UserAddedRow event does NOT refire.
Given this, it should appear clear, that trying to “grab” any of the cell values from the “new” row in the UserAddedRow event is not going to work. The best we could hope for is the first character typed by the user.
So herein lies a quandary. We want to get those values, but we need to get them “after” the user is done typing in the text. In other words, we want to get the values when the user is “done.” There are numerous ways to do this, however, whichever event(s) we choose to get the values… those events are NOT going to know if this is the “NEW” row.
Therefore, one solution is to make a global variable… we will call it LastNewRowIndex. Initially it will be set to -1 to indicate that a “new” row has not been created yet. Then we can set this variable to the row index of the “newly” added row. The grids UserAddedRow event “will” work for this. In the event, instead of trying to grab the values, simply set this LastNewRowIndex variable to the new rows index, then exit and “wait” until the user has finished.
The event may look like below. Note the (-1)… the e.Row.Index is going to point to the “just” added new row which will be the row just below the row the user is on. This is because as soon as the user typed a character into the (current) “new” row cell… the grid adds another “new” row and it becomes the “new” row. Because of this, we will KNOW that there will be at least ONE row since one was added before this event was fired.
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e) {
LastNewRowIndex = e.Row.Index -1;
}
Now, when we get to the event where we want to check the cell values, we can check if it is a cell from the “new” row by checking the LastNewRowIndex variable. If it is -1, then it is not a new row. If it is any positive number greater than -1, then that number will be the “row” in the grid that “was” the new row “before” the user typed some text into a cell in the new row.
So, the next question is… which event do I use to get those values? Obviously, there are many different ways to go. And IMHO, one is probably just as good as the other.
Following our previous example, the user types some text into the new row cell zero. The UserAddedRow event fires and we capture the new row index. As soon as the user, clicks or navigates to another cell, then we could use the grids CellValueChanged event to capture the value since it has changed. We could then check to see if LastNewRowIndex is greater than -1 to determine if this cell IS in the new row.
Using the grids, CellValueChanged event has some drawbacks, however, it may well work for some cases. IMHO, if this is a NEW row… then I really do not care if a new row’s cell value changes.
Is what I DO care about and want to know is “WHEN” the user tries to “LEAVE” the “NEW” row.
As soon as the user clicks or navigates to any cell that is NOT in the new row, THEN I want to collect those values from the new row. In other words, I do not care about the cells values if the user clicked on another cell in the same “new” row.
Granted the user may not have finished typing text into all the cells in the new row and may leave some cells null. This is a different story and is outside the scope of this example. If you wanted to make sure ALL the cells on the new row are filled in, then you could also check this in the event I use below.
Considering we need to “wait” until the user finishes adding text to all (or some) of the “new” row cells, I will assume the user is “done” when the user tries to “leave” that new row. For this I will use the grids RowLeave event to capture the cell values when the user “leaves” the new row.
First a check is made to see if LastNewRowIndex is greater than -1. If it is, then we know that the user is “leaving” the newly added row and the user has typed at least one character into one of the cells, but may have removed it also. There are no guarantees that all cell values are set. They may all well be empty or null. This may be one place where you could check to see if all the values are set in all the cells and do something if certain values are required.
Also, The grid’s RowLeave event may fire “before” the last cells edit was committed. Meaning that the last edited cell may contain the previous value and not the current value. Since we “know” that the user is “leaving” the current row, we can go ahead and commit those changes. If you do not commit the changes, then the last edited cell on the new row may not contain the newly “edited” value.
In the example below, the text box on the right display the values of both events. Additional code to complete the example.
DataTable GridTable;
int LastNewRowIndex = -1;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
GridTable = GetDT();
dataGridView1.DataSource = GridTable;
}
private DataTable GetDT() {
DataTable dt = new DataTable();
dt.Columns.Add("Col0", typeof(string));
dt.Columns.Add("Col1", typeof(string));
dt.Columns.Add("Col2", typeof(string));
for (int i = 0; i < 5; i++) {
dt.Rows.Add("C0R" + i, "C1R" + i, "C2R" + i);
}
return dt;
}
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e) {
LastNewRowIndex = e.Row.Index -1; // <- We KNOW that there is at least ONE row because it was just added
textBox1.Text += "New row being editied at row index " + LastNewRowIndex + Environment.NewLine;
}
private void dataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e) {
if (LastNewRowIndex > -1) {
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
textBox1.Text += "Leaving new row at index " + LastNewRowIndex + " cell values below" + Environment.NewLine;
DataGridViewRow dgvR = dataGridView1.Rows[LastNewRowIndex];
foreach (DataGridViewCell cell in dgvR.Cells) {
textBox1.Text += "cell[" + cell.ColumnIndex + "]= ";
if (string.IsNullOrEmpty(cell.Value.ToString())) {
textBox1.Text += "null or empty";
}
else {
textBox1.Text += cell.Value;
}
textBox1.Text += Environment.NewLine;
}
LastNewRowIndex = -1;
}
else {
// new row not set
}
}

Controling ItemChecked event after filtering data in a CheckedListBox

I have a custom UserControl that has a TextBox, a Button and a CheckedListBox.
the DataSource of the CheckedListBox is a DataTable - m_CheckBoxItems.
TextBox has a TextChanged event on it.
every letter entered into the TextBox causes the DataSource to change according to what values where found.
DataRow[] filteredRows;
if (string.IsNullOrEmpty(filter))
{
DataTable tmp = m_ChecBoxItems.Copy();
((ListBox)checkedListBox).DataSource = new BindingSource(tmp, null);
}
else
{
filteredRows = m_ChecBoxItems.Select("Text like '" + filter + "%'");
DataTable tmp = filteredRows.CopyToDataTable();
((ListBox)checkedListBox).DataSource = new BindingSource(tmp, null);
}
((ListBox)checkedListBox).DisplayMember = "Text";
((ListBox)checkedListBox).ValueMember = "Id";
now, my problem is that when i click one of the options, the OnItemClicked event fires and checks the selected index according to what the old DataSource was and then after that it get into the checkedListBox_ItemCheck event where i have some code to change the checkstate of the correct index that i intentionally click, based on where it was before the DataSource changed.
for example: m_CheckBoxItems has 100 items in it. i type "d" and the datasource changes to only values that start with "d". then i click one of the items (lets say on the second row) and then inssues the chaos. the OnItemCheck event fires containing the index that was clicked according to what i see i.e: 1 and checks that index. then it goes into checkedListBox_ItemCheck event with my own code in it and checks the original index that belonged to the specific row that i chose (lets say it was index 34).
so now i have two items checked instead of just the one that i wanted (index 34)
with every item check i also put that datarow into a list of selected datarows for future handling so that part is good, i get the row that i clicked on (index 34) and not the row that was checked by mistake (index 1).
this is my question:
how can i prevent this situation?
how can i make the checkedlistbox to check only the row that i wanted and not two rows?

column value in datagridview

i use these following codes to get cell's value in datagridview.
these codes show me each cell has been clicked.
i want to use some codes just show me special column for example column with index 1 but these codes show me each which has been clicked. Imagine i just want to show column 1 with it's clicked cell. please help me to solve this
string str = dataGridView1.CurrentCell.Value.ToString();
Thanks in advance
So you're trying to get the data from the second column for every row?
int index = 1;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewCell cell = row.Cells[index];
// Do something.
}
Edit: Per your comment, you're trying to get the value of the second column when any cell in the row is clicked. Try this:
string str = dataGridView1[1, e.RowIndex].Value.ToString();

How to select row in Telerik RadGrid?

When user select a row in Telerik Rad Grid, i want to take fields in this row. how to do this?
It's a little tricky, but easy after you've done it once.
Step 1.
Go to the Radgrid itself and edit the field DataKeyNames="" (under MasterTableView) and add the datafield you are pulling:
<MasterTableView ... DataKeyNames="ColumnNameFromSqlGoesHere">
Step 2.
Decide how you are going to grab the values, on Row Change (SelectedIndexChanged) or on a buttong press with a command attached to it (ItemCommand).
If row change, per your question:
protected void RadGrid1_SelectedIndexChanged(object sender, EventArgs e)
{
var z = RadGrid1.SelectedItems[0].OwnerTableView.DataKeyValues[RadGrid1.SelectedItems[0].ItemIndex]["ColumnNameFromSqlGoesHere"];
}
This will assign the variable "z" to the value of the column you have chosen (ColumnNameFromSqlGoesHere) at that given row.
If you wish to select multiple variables every time you change row you need to add all the values you wish to select under the DataKeyNames=" ". (Seperated by commas). You would then fetch each value via the code seen in the SelectedIndexChanged method:
var a = RadGrid1.SelectedItems[0].OwnerTableView.DataKeyValues[RadGrid1.SelectedItems[0].ItemIndex]["SecondColumnGoesHere"];
var b = RadGrid1.SelectedItems[0].OwnerTableView.DataKeyValues[RadGrid1.SelectedItems[0].ItemIndex]["ThirdColumnGoesHere"];
Etc... You get the idea.
This should get you going. It is a solution straight from Telerik: Retrieving primary key values for selected items
Try this. This may help you.
STEP 1:Add one radiobutton column in the radgrid
STEP 1: Get the primary key of selected row in the radgrid.
int primaryKey =0;
RadioButton radioButton;
for (int i = 0; i < RadGrid1.Items.Count; i++)
{
radioButton = RadGrid1.Items[i].FindControl("rdSelect") as RadioButton;
If (radioButton.Checked)
{
primaryKey = RadGrid1.MasterTableView.Items[e.Item.ItemIndex]["ID"].Text;
}
}
Line in the if condition will be used to get the fields from the selected row just by changing the fields datakey name i.e. changing "ID" to other field
Read this article for more details...
http://codedotnets.blogspot.in/2012/01/get-primary-key-selected-radiobutton.html

Check DatagridView is empty(has no values) or not?

I have a 3X3 grid which on creation has empty(has no values) cells.
I want to check whether user has key-in some some data into the cell's or not.
Its not binded to any data-source. I don't want to iterate through each cell and check for the data and break on the first data found.
I want some small solution for the same. As same thing has to be done on many forms. I will make some generic routine or extension method for the same.
PS:
What I have is a grid with three paramter
ParamA ParamB ParamC
Short
Medium
Long
when user fill any of the data. I have to add it to a collection. If no data is key inned then do nothing.
Consider using the KeyPress event or perhaps even better would be the CellEndEdit on MSDN
The following shows a message box of where you were and the cell contents(Correction):
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
string message = string.Format("Cell End Edit: just left row: {0} and column {1}.\n Value entered:{2}", e.RowIndex, e.ColumnIndex,
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].FormattedValue.ToString());
MessageBox.Show(this, message, "You were here");
}
For reuse you may create your own user control or create a base form class.
You can create a integer value EmptyFieldsCount, and update it every time the user updates a cell.
With 1 column is check box if checked is true then:
Dim dgv1 As DataGridViewRow = DataGridView1.Rows(e.RowIndex)
Dim headerText As String = DataGridView1.Columns(e.ColumnIndex).HeaderText
If dgv1.Cells(0).Value = True Then
If Not headerText.Equals("Short Desc") Then Return
If String.IsNullOrEmpty(e.FormattedValue.ToString()) Then
DataGridView1.Rows(e.RowIndex).ErrorText = "Short Desc Can not be blank ! "
e.Cancel = True
End If
End If
Without checkbox:
Dim dgv1 As DataGridViewRow = DataGridView1.Rows(e.RowIndex)
Dim headerText As String = DataGridView1.Columns(e.ColumnIndex).HeaderText
If Not headerText.Equals("Short Desc") Then Return
If String.IsNullOrEmpty(e.FormattedValue.ToString()) Then
DataGridView1.Rows(e.RowIndex).ErrorText = "Short Desc Can not be blank ! "
e.Cancel = True
End If**

Categories

Resources