I'm trying to get my current program to take information from a dynamically created DataGridView. I have managed to get the information into the grid, and perform the required search, however now I'm really stuck.
I have added a column to the datagridview which holds a button within each row. What I'd like to do is take the value of the data from column index 1 which is in the same row as the button clicked. Confusing? Anyway, here's the code:
public void GetValues(...)
{
//Details regarding connection, querying and inserting table
.
.
.
DataGridViewButtonColumn buttonCol = new DataGridViewButtonColumn();
buttonCol.Name = "ButtonColumn";
buttonCol.HeaderText = "Select";
buttonCol.Text = "Edit";
//NB: the text won't show up on the button. Any help there either?
dataGridView1.Columns.Add(buttonCol);
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewButtonCell button = (row.Cells["ButtonColumn"] as DataGridViewButtonCell);
}
dataGridView1.Columns["ButtonColumn"].DisplayIndex = 0;
}
void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//Here is where I'm having the trouble. What do I put in here???
}
Thanks for any help you can give!
David.
Your DataGridViewCellEventArgs contains very useful information such as RowIndex.
So something like (I don't know what you want to do with the value):
String dataYouWant = dataGridView1.Rows[e.RowIndex].Cells[1].Value;
`
if (e.ColumnIndex != button_column_number) //column number of the button.
return;
dataGridView1.EndEdit();
bool val;
if ((dataGridView1.Rows[e.RowIndex].Cells[1].Value) != null) // column index 1...as that's what you want.
{
//d stuff you want here.
}
else
{
}
`
Related
How can I get the variables that are in two specific columns in DataGridView, for example I want the Id that is in the first column and the name that is on the third. How can I do that? I'm trying the RowEnter event but when I searched online I can't find anything that I can follow up. Thanks guys.
private void dataGridViewDocumentos_RowEnter(object sender, DataGridViewCellEventArgs e)
{
DataGridViewRow dgvr = dataGridViewDocumentos.SelectedRows[0];
dgvr.Cells[];
foreach (DataGridViewRow Datarow in contentTable_dgvr.Rows)
{
if (dgvr.Value != null && Datarow.Cells[1].Value != null)
{
int contentJobId = 0;
contentJobId = Datarow.Cells[0].Value.ToString();
contentValue2 = Datarow.Cells[1].Value.ToString();
MessageBox.Show(contentValue1);
MessageBox.Show(contentValue2);
}
}
}
This is what I have right now, as you guys can see I'm missing a lot of things, I'm not familiar with this so if you guys can point what I need to do I'd appreciate it.
Well, the 1st question is, is this on a button click outside the grid? Or is this in response to an specific event that has happens? The reason why I ask that is because in your code sample you are using the RowEnter event which will fire everytime the row recieves input. I am not sure if that is what you want ot not.
Anyway, I mean you are pretty much there with your code sample. If you want to get the selected 1st and 3rd column for the selected row you could use this code.
private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
{
var activeCell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex];
var fistColumnCell = dataGridView1.Rows[e.RowIndex].Cells[0];
var thirdColumnCell = dataGridView1.Rows[e.RowIndex].Cells[2];
MessageBox.Show(fistColumnCell.Value.ToString());
MessageBox.Show(thirdColumnCell.Value.ToString());
}
Notice that the 2nd paramater of the function named DataGridViewCellEventArgs has properties for ColumnIndex and RowIndex which you can use to get the currently selected row.
However, if this code should fire in response to a user double clicking a cell you could use the CellDoubleClick event
private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
var fistColumnCell = dataGridView1.Rows[e.RowIndex].Cells[0];
var thirdColumnCell = dataGridView1.Rows[e.RowIndex].Cells[2];
MessageBox.Show(fistColumnCell.Value.ToString());
MessageBox.Show(thirdColumnCell.Value.ToString());
}
I'm working in C# displaying some data in a DataGridView and I'd like it to not allow you to add a duplicate key.. Right now, my DataGridview is pretty simple with just 2 columns. One is called "Key" the other is called "Value". What i want, is for when the user edits or adds a new entry to the DataGridView, it checks if there is already a duplicate and cancels the edit/creation of the new row. Here is my current code:
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[0].Value.Equals(dataGridView1.Rows[e.RowIndex].Cells[0].Value))
{
dataGridView1.Rows.Remove(dataGridView1.Rows[e.RowIndex]);
break;
}
}
refresh();
}
It isn't working at all... Can someone tell me how I should be doing this?.. Thanks!
Edit: I'm also getting this error on the dataGridView1.Rows.Remove() call -
Operation is not valid because it results in a reentrant call to the SetCurrentCellAddressCore function.
Edit:
The DataGridView looks like this
Key | Value
----------------
blah | something
somekey | somevalue
It is probably your foreach loop, which doesn't allow deleting rows.
Try something like this:
private void dgv_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
for (int i = 0; i < DataGridView1.Rows.Count; i++) {
DataGridViewRow row = DataGridView1.Rows[i];
if (row.Cells[0].Value == DataGridView1.Rows[e.RowIndex].Cells[0].Value) {
DataGridView1.Rows.RemoveAt(e.RowIndex);
DataGridView1.FirstDisplayedScrollingRowIndex = i;
return;
}
}
}
I do not allow row editing, though, so I could be wrong.
EDIT: Just a quick edit. I'd set the FirstDisplayedScrollingRowIndex to e.RowIndex, but that row would have just been deleted!
I'm only guessing but I've tried your code and I've seen a logical error:
if you debug it you'll see that with the foreach loop you'll necessary hit the element you just edited, which is obviously equal to itself.
I suggest you to change the loop to a for or to check if the row index is the same.
try with this code for that,
protected void GV_RowCommand(object sender, GridViewCommandEventArgs e)
{
DataTable dt1 = ViewState["dt"] as DataTable;
if (e.CommandName == "Add")
{
DataRow dr;
dr = dt1.NewRow();
dr["DED_Id"] = Material_Id;
dr["DED_Name"] = Material;
dt1.Rows.Add(dr);
dt1.AcceptChanges();
ViewState["dt"] = dt1;
}
}
I have this code in my C# program, but it throws a fit when some buttons are clicked because there is no row selected in the DataGridView (I use the ClearSelection method):
string selectedUser = usersGrid.SelectedRows[0].Cells[1].Value.ToString();
Is there some sort of check I can do before the above line to ensure that a row is selected?
if (usersGrid.SelectedRows.Count > 0)
I am going to take a stab at what I think you are trying to do, try this below
private void myButton_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in usersGrid.Rows)
{
if (this.usersGrid.SelectedRows.Count == 1)
{
// get information of 1st column from the row
string selectedUser = this.usersGrid.SelectedRows[0].Cells[0].ToString();
}
}
}
also do the following as well and checkout the link
Set DataGridView.MultiSelect=false and DataGridView.SelectionMode = FullRowSelect. This will make it so the user can only select a single row at a time.
I have a datagridview with multiple checkboxes. When the Finished checkbox is checked I need to execute linq code to update a specific table. How do I find out if that specific check box is dirty and where do I write the code to pass the values I need to be passed to the table. Note that it is not the same table that the datagridview is based on.
Thanks.
EDIT:
private void propertyInformationDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)propertyInformationDataGridView.Rows[e.RowIndex].Cells[3];
DataGridViewRow row = propertyInformationDataGridView.Rows[e.RowIndex] as DataGridViewRow;
System.Data.DataRowView SelectedRowView;
newCityCollectionDataSet.PropertyInformationRow SelectedRow;
SelectedRowView = (System.Data.DataRowView)propertyInformationBindingSource.Current;
SelectedRow = (newCityCollectionDataSet.PropertyInformationRow)SelectedRowView.Row;
if (Convert.ToBoolean(checkCell.EditedFormattedValue) == true)
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var matchedCaseNumber = (from c in dc.GetTable<PropertyInformation>()
where c.CaseNumberKey == SelectedRow.CaseNumberKey
select c).SingleOrDefault();
reportsSent newReport = new reportsSent();
newReport.CaseNumberKey = SelectedRow.CaseNumberKey;
dc.reportsSents.InsertOnSubmit(newReport);
dc.SubmitChanges();
}
}
Do I need to endedit at some point is that the issue?
This is from some of my code, all you need to do is create a "CellContentClick" event for your datagridview.
The easiest way to do this is select the Datagridview, go to properties and click on the lightning bolt. Scroll down to "CellContentClick" and double click in the empty box. This will auto generate the method you need to paste the following code into.
Make sure you rename my instances of "CustomersDataGridView" to whatever yours is named as well, intellisense should highlight invalid code in red that you need to replace.
Also, the "9" you see in the checkCell declaration needs to be changed to the index of your "Finished" check-box. If it is in the 3rd cell from the left, put a 2 there instead of a 9, as the indexing is 0 based.
EDITTED to fix comments:
private void CustomersDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex.ToString() == "9")
{
DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)CustomersDataGridView.Rows[e.RowIndex].Cells[9];
DataGridViewRow row = CustomersDataGridView.Rows[e.RowIndex] as DataGridViewRow;
if (Convert.ToBoolean(checkCell.EditedFormattedValue) && CustomersDataGridView.IsCurrentCellDirty)
{
//Do Work here.
var z = row.Cells[0].Value; // Fill in the brackets with the column you want to fetch values from
//z in this case would be the value of whatever was in the first cell in the row of the checkbox I clicked
}
}
}
You can do it in the CheckedChanged-Event
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
// Do what you have to do...
}
I have a datagrid with 2 columns. One is a checkbox and one is a normal textbox cell. All is bound to one BindingList which is an entity.
If I check one checkbox and then loop to get the checked entities from the BindingList, it returns nothing. But if I check then edit the textbox column, it works just fine and return one result.
I tried to refresh or to check then click somewhere else. It doesn't work.
How do you manage to get your bindingList updated when you check a column?
Thank you!
What data type is the column in the data source (dataTable)? Is it boolean type?
But this doesnt matter so much, what matters is that you use the correct event of the dgv.
Use:
1. CurrentCellDirtyStateChanged and
2. CellValueChanged
This is the code you have to use:
private void CreateAndBind()
{
DataTable table = GetDataToDataTable();
//then bind it to dgv:
dgv.DataSource = new BindingSource(table, null);
//create events for dgv:
dgv.CurrentCellDirtyStateChanged += new EventHandler(dgv_CurrentCellDirtyStateChanged);
dgv.CellValueChanged += new EventHandler(dgv_CellValueChanged);
}
private DataTable GetDataToDataTable()
{
//get data from dataBase, or what ever...
table.Columns.Add("column1", typeof(stirng));
table.Columns.Add("column2", typeof(bool));
//adding some exmaple rows:
table.Rows.Add("item 1", true);
table.Rows.Add("item 2", false);
return table;
}
void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
private void dgv_CellValueChanged(object obj, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == 0) //compare to checkBox column index
{
DataGridViewCheckBoxCell check = dataGridView1[0, e.RowIndex] as DataGridViewCheckBoxCell;
if (Convert.ToBoolean(check.Value) == true)
{
//If tick is added!
//
}
}
}
Hope it helps.