No Duplicates in DataGridView - c#

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;
}
}

Related

Delete row from datatable

I want to delete rows from my dataset. Below is the code...
When the checkbox is selected a value is getting stored as a hiddenfield value
The code is not firing. The values are not getting added to the "rowstodelete".
protected void BtnRmvFile_Click(object sender, EventArgs e)
{
string[] IDs = hdnFldSelectedValuesAp.Value.Trim().Split('|');
//Code for adding items
foreach (string Item in IDs)
{
try
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
ViewState["CurrentTable"] = dtCurrentTable;
List<DataRow> rowsToDelete = new List<DataRow>();
foreach (DataRow row in dtCurrentTable.Rows)
{
if ((row["FileMasterID"] == Item))
{
rowsToDelete.Add(row);
}
}
foreach (DataRow row in rowsToDelete)
{
row.Delete();
}
dtCurrentTable.AcceptChanges();
}
If you say the code is not firing i suggest to start by checking with some kind of pop up that your method(BtnRmvFile_Click) is responding.
Other than that I don't know if its just the way you pasted the code but make sure the brackets are organized.
If the method responds to the click event start debugging, see which steps are executed and what values you pass/get make sure that its what you expect.
Good luck!

how to sum the column which is in the dataset and display in the footer

Here is my code:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
try
{
int IndexTypeID = 5;
mobjORACLE = new DatabaseObjects.OracleDBCalls();
DataSet dsetPortfolio = mobjORACLE.GetORACLEDataSet(IndexTypeID, "v_indextypeid", "cv_1", "fn_getportfolio");
if (dsetPortfolio.Tables[0].Rows.Count > 0)
{
ViewState["gvPortfolio_DataSource"] = dsetPortfolio.Tables[0];
gvPortfolio.DataSource = dsetPortfolio.Tables[0];
gvPortfolio.DataBind();
gvPortfolio.Visible = true;
//dsetPortfolio.Tables[0].Rows[0]["cashreserve"];
//ViewState["gvPortfolio_DataSource"] = gvPortfolio.DataSource;
gvPortfolio.Attributes.Add("bordercolor", "#999966");
}
}
catch (Exception ex)
{
throw ex;
}
}
}
In gvPortfolio i got a datatable which has a column by name amount allocated. Now the question is, i need to sum up the column and display its result in the footer. Can somebody help me out in getting out of this.
You would use the GridView.RowDataBound Event.
Excerpt from Microsoft Documentation:
Before the GridView control can be rendered, each row in the control
must be bound to a record in the data source. The RowDataBound event
is raised when a data row (represented by a GridViewRow object) is
bound to data in the GridView control. This enables you to provide an
event-handling method that performs a custom routine, such as
modifying the values of the data bound to the row, whenever this event
occurs.
For example:
void gvPortfolio_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Footer)
{
// Once you know you are in the footer row
// the sender object is the GridView and you can get the datasource
// loop thru the datatable adding up the values you want
// For example: let say column 3 have the number
// **** code is not tested - writing from memory ***
int total = 0;
int column = 3;
foreach(DataRow row in (DataTable)(sender.DataSource).Rows)
{
if (!row.IsNull(column))
{
// probably need more checking to make sure we have a valid integer
total += Convert.ToInt32(row[column]);
}
}
e.Row.Cells[column].Text = total.ToString();
}
}
Good morning I believe that this previous post should help you with what you are trying to accomplish.

How do I execute code after a certain checkbox is selected

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...
}

Checkbox in datagrid view doesn't update my bindingList

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.

C# dynamically taking data from DataGridView

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
{
}
`

Categories