How to get a GridView's selected Id? - c#

I have a GridView that uses the select. I want to grab the RegistrantId of which row is selected. I've tried a bunch of ways and haven't had luck.
C#
GridViewRow row = GridView1.SelectedRow;
if ((row != null))
{
string registrantId = GridView1.Rows[e.RowIndex].Cells[0].Value.ToString();
PnlEdit.Visible = true;
}
I need to figure out what to put at string registrantId =. It needs to equal the value of the RegistrantId from that row.
This attempt above, for example, gives me a compile error for RowIndex stating that "EventArgs does not contain a definition for RowIndex."

You can find the RowIndex like so:
string registrantId = GridView1.DataKeys[e.RowIndex]
This assumes that you have the DataKeyNames property set in your gridview
<asp:GridView runat="server" ID="GridView1" DataKeyNames="RegistrantId" >
Also, if this method is triggered by an event handler, you might want to change your null check condition to:
protected void GridView1_RowSelecting(object sender, GridViewSelectEventArgs e)
{
var registrantId = GridView1.DataKeys[e.RowIndex];
if(registrantId != null)
{
PnlEdit.Visible = true;
}
}
(You know the row exists because it was selected and that selection is what causes the event to trigger. The null check confirms you were able to obtain the registrantId from the row)

Related

How to exclusively set the value of a DataGridViewCheckBoxCell?

I have a List<Car> objects that have a bool property named Marked.
I want to check / uncheck the Cell corresponding to this property, in a way that only one Car can be selected at the same time.
I want that the value of this property is updated in the bank.
Sample table:
Car Name
Marked
a
 
b
 
The problem is I can't check the state of CheckBox Cells.
This is what I tried, but it's not working:
Example 1:
DataGridViewCheckBoxCell dataGridViewCheckBoxCell = DataGridView1.Rows[e.RowIndex].Cells["Marked"] as DataGridViewCheckBoxCell;
if(Convert.ToBoolean(dataGridViewCheckBoxCell.Value) == true)
{
//some code
}
else if(Convert.ToBoolean(dataGridViewCheckBoxCell.Value) == false)
{
//some code
}
Example 2:
foreach (DataGridViewRow row in DataGridView1.Rows)
{
DataGridViewCheckBoxCell chk =(DataGridViewCheckBoxCell)row.Cells["Marked"];
if (chk.Value == chk.TrueValue)
{
chk.Value = chk.FalseValue;
}
else
{
chk.Value = chk.TrueValue;
}
}
how can I do it?
You can handle the CellContentClick (or CellClick) event of your DataGridView to set the state of a DataGridViewCheckBoxCell that should be a single choice (hence behaving as a RadioButton).
Store the Cell object currently selected when the Cell meets the criteria (its OwningColumn is a DataGridViewCheckBoxColumn named Marked).
Change the state of this Cell if it's the one currently selected, or reset it back to false if it's not.
In this case, set the current Cell to the one just selected and set its state to true.
Then you don't need to loop all the Rows each time a CheckBox changes value.
If you need to, call [DataGridView].EndEdit() to update the value immediately.
For example:
DataGridViewCheckBoxCell currentCheckBoxCell = null;
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
var dgv = sender as DataGridView;
if (dgv[e.ColumnIndex, e.RowIndex] is DataGridViewCheckBoxCell cell &&
cell.OwningColumn.Name == "Marked")
{
if (currentCheckBoxCell is null) currentCheckBoxCell = cell;
if (cell == currentCheckBoxCell) {
cell.Value = !(bool)cell.Value;
}
else {
currentCheckBoxCell.Value = false;
currentCheckBoxCell = cell;
}
// Affects CellValueChanged
// dgv.EndEdit();
}
}
This is how it works:
See also DataGridView CheckBox selection bug to select a CheckBox Cell by clicking anywhere in a Row and while immediately update the data source.
It is unclear “where” the first code snippet is called from so I will focus on the second snippet of code.
One of the problems you will have comes from the if statement…
if (chk.Value == chk.TrueValue) …
This condition chk.Value == chk.TrueValue may not throw an error, HOWEVER… this is checking two different OBJECTS… chk.Value is an OBJECT as is chk.TrueValue … so it makes sense that the two “different” OBJECTS would NEVER be equal.
One way to solve this is to simply “cast” those OBJECTS to bool values like…
if ((bool)chk.Value == (bool)chk.TrueValue) {…
HOWEVER the above line of code will ONLY work “IF”… the check box columns TrueValue AND FalseValue properties have been SET like…
CheckBoxColumn.TrueValue = true;
CheckBoxColumn.FalseValue = false;
IF you have NOT set the Check box column’s two properties TrueValue AND FalseValue like above… then the Check box columns TrueValue and FalseValue will be null and this will cause the line of code … if ((bool)chk.Value == (bool)chk.TrueValue) … to throw an exception since chk.TrueValue is null and the cast to a bool will throw a null exception.
Therefore, if you DO SET the Check box columns TrueValue and FalseValue then you will have to “cast” the objects to bool values in order for the comparison to work as shown above.
Given all this… you may want to re-consider using the Check box columns TrueValue and FalseValue as the intended purpose of those properties is to allow you to “change” the actual true and false values to something else that is not necessarily a true or false value.
It is unimportant how you would use these properties in that context as it appears very clear that in this context… setting the Check box columns TrueValue and FalseValue properties to true and false is somewhat superfluous and creates more work for you.
So in this case, I suggest you completely drop using the Check box columns TrueValue and FalseValue properties.
If you want to ensure that only ONE check box is checked in the column… then you could wire up the grids CellContentClick event. If the check box value changed, then simply “uncheck” all the cells in that column.
Fortunately, the grids CellContentClick will fire “before” it actually sets the check box cell, so unchecking them all works out fine for both checked and unchecked states. Crude yes, but it should work.
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) {
if (dataGridView1.Columns[e.ColumnIndex].Name == "Marked") {
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (!row.IsNewRow) {
row.Cells["Marked"].Value = false;
}
}
}
}
I hope this makes sense and helps.

Searching a name in a gridview C#

This is the table. On the right are the namesI have a gridview that shows a table from the database. I want to search a name in the gridview using a textbox and a button. This is what i have so far. When i want to search I get in a messagebox this: object reference is not set on an instance of an object.
private void btn_zoek_Click(object sender, EventArgs e)
{
string searchValue = tb_SearchOverzicht.Text;
metroGrid1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
try
{
foreach (DataGridViewRow row in metroGrid1.Rows)
{
if (row.Cells[2].Value.ToString().Equals(searchValue))
{
row.Selected = true;
break;
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
Check if the values and object you are trying to work with are filled with data and not null.
In your row
if (row.Cells[2].Value.ToString().Equals(searchValue))
you should check first, if the cell exists and has value, like this:
if(row.Cells[2] != null && row.Cells[2].Value.ToString() == searchValue)
{
// Some code
}
and just to be sure, check if your searchValue is not empty or without any chars or maybe even correct formatted:
if(!String.IsNullOrWhiteSpace(searchValue))
but I dont think this is necessary here, just nice to have.
The goal here is: Not all values have to be filled. It can appear that a cell doesnt have value in that column, the row may be the filter row or even empty, or worst: the grid isn't even initialized. So please try to check if values or objects are filled before using them.

Updating Records in Gridview Using EF

I have a webpage with a gridview attached to it. The gridview allows the user to update individual records. The gridview looks like this:
JobSiteID JobSite1
1 13-03
2 13-04
3 13-06
4 13-09
5 13-15
I created the following record updating event handler:
protected void changeJobSiteRecordsGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
GridViewRow row = changeJobSiteRecordsGridView.Rows[e.RowIndex];
TextBox txtJobSite = row.FindControl("txtJobSite") as TextBox;
if (txtJobSite != null)
{
using (ABCEntities4 Context = new ABCEntities4())
{
int jobSiteID = Convert.ToInt32(changeJobSiteRecordsGridView.DataKeys[e.RowIndex].Value);
JobSite obj = Context.JobSites.First(x => x.JobSiteID == jobSiteID);
obj.JobSite1 = txtJobSite.Text;
Context.SaveChanges();
changeJobSiteRecordsGridView.EditIndex = -1;
changeJobSiteRecordsGridView.DataSource = Context.JobSites;
changeJobSiteRecordsGridView.DataBind();
}
}
}
Here's my problem:
When I select to update, say row #2, on the first line, the local "row" variable indicates that the RowIndex == 1.
However, in the second line, I expect txtJobSite variable to be populated with "13-04" but VS assigns "null" to the variable.
As a result, the code flows over the if then statement below which isn't what was intended.
Any help would be greatly appreciated.
Thanks.
Check the row's cells property like this:
row.Cells[1].Controls[0]
for the text box. If the '0' index doesn't work, try the 1 index. Then your code would look something like this:
TextBox txtJobSite = (TextBox)row.Cells[1].Controls[1]
I remember running into a similar problem with FindControl. This way, you explicitly find the cell and then the control in the cell.

Using DataGrid ItemDataBound Event to Check Value

I've got a DataGrid where the datasource is bound with a SqlDataReader object:
SqlDataReader areader = runner.Reader;
dgSearchResults.DataSource = areader;
dgSearchResults.DataBind();
I've created an ItemDataBound event for my grid and I want to check the Value of a specific Column/Cell that while each item is bound so I can enable/disable some flags.
How can I get the value of a specific cell "SvcID" on the ItemDataBound?
Here is my code:
public void dgSearchResults_ItemDataBound(object sender, DataGridItemEventArgs e)
{
if (ViewState["SvcIDs"] != null)
{
if (e.Item != null)
{
var svcIds = (List<int>) ViewState["SvcIDs"];
if (svcIds.Contains(Convert.ToInt32(**DataGrid SvcID Goes Here**))
{
//TODO: enable/disable some icons
}
}
}
}
I've used RowDataBound events before but not for a DataGrid control, and the required steps are a bit different it seems.
What is the code to check the value of Column "SvcID" in my DataGrid against my SvcIds (using an Index) List?
Thanks
You can use the following to access the cells:
e.Item.Cells[index].Text;
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.datagriditemeventargs.item.aspx
if your text is in second cell.
ex
e.Item.Cells[2].Text
Unfortunately you cant index the Cell collection using a column name or the databound field name.
To do that you need to know the index of the datafield (e.g. SvcID in your case) and index the Row object. If you are using AutogenerateColumns then the index would be based on the order of columns you are querying from the database.
Then you can handle the RowDataBound event, which has an event argument of type GridViewRowEventArgs that gives u access to the DataGridView row instance. then you can do something like this:
string val= e.Row.Cells(index).Text;

Selecting rows programmatically in DataGridView

I want to select row of previously selected rows after some event my code is as below.
int currentRow = dgvIcbSubsInfo.CurrentCell.RowIndex;
//code to execute
dgvIcbSubsInfo.Rows[currentRow].Selected = true;
after executing the code the preview will be as below. but i need to get the symbol > in id = 1272741 (blue selection) and not in 1272737
Probably you might have taken a look at the DataGridView.CurrentRow Property, which is a read-only property:
Gets the row containing the current cell.
But in the remarks section, there is written:
To change the current row, you must set the CurrentCell property to a
cell in the desired row.
Also, from the DataGridView.CurrentCell Property, we find out that:
When you change the value of this property, the SelectionChanged event
occurs before the CurrentCellChanged event. Any SelectionChanged event
handler accessing the CurrentCell property at this time will get its
previous value.
So, there is no need that you actually select the currentRow becasue it will be selected when you set the CurrentCell value (unless you have some code to be executed inside the current scope between the SelectionChanged and CurrentCellChanged events). Try this:
//dgvIcbSubsInfo.Rows[currentRow].Selected = true;
dgvIcbSubsInfo.CurrentCell = dgvIcbSubsInfo.Rows[currentRow].Cells[0];
I think you wish to highlight the row. Please try following code, I think it might help:
Color color = dgv.Rows[prevRowIndex].DefaultCellStyle.SelectionBackColor;
dgv.Rows[curRowIndex].DefaultCellStyle.SelectionBackColor = color;
Try the following to change the current row. Since the OP is a little unclear as to what row should be the new row, my example simply shows moving from the current row to the previous row (if there is a previous row). The first line of code is optional. You can also hardcode col to 0 (or some other column) to use a fixed column if you don't want to use FullRowSelect.
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
int row = dataGridView.CurrentCell.RowIndex;
int firstRow = dataGridView.Rows.GetFirstRow(DataGridViewElementStates.None);
if (row != firstRow)
{
row--;
int col = dataGridView.CurrentCell.ColumnIndex;
dataGridView.CurrentCell = dataGridView[col, row];
}
I came here wanting to learn how to programmatically select rows in a DataGridView control. Here is how to select the top row in your DataGridView control named dg1 and "click" it:
dg1.Rows[0].Selected = true;
dg1_RowHeaderMouseClick(null, null);
This then calls the following event which is expecting one selected row.
private void dg1_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
var selectedRows = dg1.SelectedRows;
// Make sure we have a single row selected
int count = selectedRows.Count;
if (count == 1)
{
tbAssemblyName.Text = dg1.SelectedRows[0].Cells[0].Value.ToString();
}
}
I had everything working when the user clicked the row they wanted. When there was only one record to choose from I wanted to "click" it for the user.

Categories

Resources