I want to delete row from datagridview when user clicks the delete button.The datagridview bounded to datatable _dt so i remove the row from _dt and try to rebind the modified _dt to datagridview but instead of deleting the row gets added to the last row of the datagridview what am I doing wrong here
private void btnDelete_Click(object sender, EventArgs e)
{
if (dataGridView1 != null && dataGridView1.SelectedRows.Count == 1)
{
string key = dataGridView1.SelectedRows[0].Cells["ID"].Value.ToString();
DataColumn[] keyColumns = new DataColumn[1];
keyColumns[0] = _dt.Columns["ID"];
_dt.PrimaryKey = keyColumns;
rowToDelete = _dt.Rows.Find(key);
_dt.Rows.Remove(rowToDelete);
_dt.AcceptChanges();
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
dataGridView1.DataSource = null;
dataGridView1.DataSource = _dt;
}
}
No need for Fill before update and also delete this row
_dt.AcceptChanges();
because this will remove the row from memory and when you call update
only the remaining rows are updated, it will not delete the row from database.
No need to call Fill Before Update, because Fill will get data again from db and your changes will be lost. So This will work for you.
SqlCommandBuilder cb = new SqlCommandBuilder(_sqlDa);
//_sqlDa.Fill(_dt);
_sqlDa.Update(_dt);
Related
I want to click on an exact row in a WinTable where my criteria meets but couldnt succeed so far. I can search criteria for an exact row but I can not get total number of rows so that I would make a loop for all rows. I tried collection and table.Rows.Count,but both brings nothing to me. Can someone help me on this ?
#region Variable Declarations
WinTable uIG1Table = this.UIProMANAGEWindow.UIDefinitionsWindow.UIG1Window.UIG1Table;
WinRow dataGridrow = uIG1Table.GetRow(0);
#endregion
UITestControlCollection rows = uIG1Table.Rows;
// MessageBox.Show(rows[5].RowIndex.ToString());
foreach (WinRow row in uIG1Table.Rows)
{
foreach (WinCell cell in row.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
and this is the code with for loop
int rows = uIG1Table.Rows.Count;
for (int i = 0; i < rows; i++)
{
foreach (WinCell cell in dataGridrow.Cells)
{
if (cell.Value.ToString() == "E81")
Mouse.Click(cell, new Point(5, 0));
}
}
When doing a GetChildren() on a row, you will notice that the first child is of type RowHeader. A user typically clicks the row header to select the row.
Following code will iterate all the rows in a DataGridView and click the row header, effectively selecting the row:
UITestControlCollection rows = YourUIMapTable.Rows;
foreach (UITestControl row in rows)
{
UITestControl rowHeader = row.GetChildren().Single(child => child.ControlType == ControlType.RowHeader);
Mouse.Click(rowHeader);
}
If you want to select a specific row, you can do something like this:
Mouse.Click(YourUIMapTable.Rows[putIndexNumberHere].GetChildren().Single(child => child.ControlType == ControlType.RowHeader));
The sample code above is based on the program I wrote in my answer to this question:
How to get cell color information of a WinCell with codedui?
I am using C1FlexGrid on windows forms.
I have SELECT column in the grid which of type Checkbox.
I have an edit button outside the grid on the form.
Initially I want the Select column in the grid to be disabled.
Upon clicking Edit Button, I want the Select column to be enabled (so that it can be ticked for each row)
Once I press save, I want to disable Select Column again.
Any idea ?
I am assuming that you have used CheckBoxes in a C1lexGrid column by changing the columns datatype to boolean. It is very easy to stop the user from interacting with a particular column in C1FlexGrid. Refer the following snippet:
C#
// Assuming the checkboxes are in column 1
private void Save_Click(object sender, EventArgs e)
{
//...
// Save the flexgrid..
//...
// disable the column
this.c1FlexGrid1.Cols[1].AllowEditing = false;
this.c1FlexGrid1.Cols[1].AllowDragging = false;
this.c1FlexGrid1.Cols[1].AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None;
this.c1FlexGrid1.Cols[1].AllowSorting = false;
}
private void Edit_Click(object sender, EventArgs e)
{
this.c1FlexGrid1.Cols[1].AllowEditing = true;
this.c1FlexGrid1.Cols[1].AllowDragging = true;
this.c1FlexGrid1.Cols[1].AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None;
this.c1FlexGrid1.Cols[1].AllowSorting = true;
}
VB
'Assuming the checkboxes are in column 1
Private Sub Save_Click(sender As Object, e As EventArgs) Handles Save.Click
'...
' Save the flexgrid..
'...
' disable the column
Me.c1FlexGrid1.Cols(1).AllowEditing = False
Me.c1FlexGrid1.Cols(1).AllowDragging = False
Me.c1FlexGrid1.Cols(1).AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None
Me.c1FlexGrid1.Cols(1).AllowSorting = False
End Sub
Private Sub Edit_Click(sender As Object, e As EventArgs) Handles Edit.Click
Me.c1FlexGrid1.Cols(1).AllowEditing = True
Me.c1FlexGrid1.Cols(1).AllowDragging = True
Me.c1FlexGrid1.Cols(1).AllowFiltering = C1.Win.C1FlexGrid.AllowFiltering.None
Me.c1FlexGrid1.Cols(1).AllowSorting = True
End Sub
I have a datatable problem when I reject changes on the table. I've created an example below which demonstrates the problem:
DataTable table = new DataTable();
table.Columns.Add("Name", typeof(string));
table.Columns.Add("Last_Name", typeof(string));
table.Columns.Add("Male", typeof(Boolean));
foreach (DataColumn column in table.Columns)
{
if (column.ColumnName == "Name")
{
column.Unique = true;
}
}
DataRow row;
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
table.AcceptChanges();
So at this stage I have a DataTable with a unique column constraint and 1 row in that table.
I now delete that row:
row.Delete();
This sets the rowstate to Deleted.
At this stage I realise that I've made a mistake and want to add the row again. So I create the new row again and add it to the DataTable:
row = table.NewRow();
row["Name"] = String.Format("Steve");
row["Last_Name"] = String.Format("Smith");
row["Male"] = true;
table.Rows.Add(row);
At this stage my DataTable contents are in the following state:
table.Rows[0].RowState is Deleted
table.Rows[1].RowState is Added
Now, I've changed my mind about the whole thing and want to get back to how I started so I call RejectChanges:
table.RejectChanges();
When I do this I receive the following error:
Column 'Name' is constrained to be unique. Value 'Steve' is already present.
I understand that there are 2 rows with the same values but I thought reject changes would have ingored this as the RowStates are different.
Any ideas how I can get round this?
In my live code I use this to move rows between to 2 grids (like allowing the user to selected what columns are visible)
I'm using C#4.0 in Visual Studio 2012
Thanks in advance
I am creating grid view through data adapter and all columns and rows are created from data base but problem occurs that when rows all rows are created there comes another empty row i want to stop that row to be generated and when i click and some value in that extra row another new row is created i want to stop all extra rows how to do this any help???
this is the grid view code i am using
conn.ConnectionString = s;
conn.Open();
dAdapter = new SqlDataAdapter(query, s);
dTable = new DataTable();
DataView myDataView = dTable.DefaultView;
dAdapter.Fill(dTable);
BindingSource bndSource = new BindingSource();
bndSource.DataSource = dTable;
dataGrid.DataSource = bndSource;
dataGrid.Columns["StudentId"].ReadOnly = true;
dataGrid.Columns["StudentName"].ReadOnly = true;
conn.Close();
Try setting AllowUserToAddRows to false.
I am using openxml to create an excel report. The openxml operates on a template excel file using named ranges.
The client requires a totals row at the end of the list of rows. Sounds like a reasonable request!!
However, the data table I'm returning from the db can contain any number of rows. Using template rows and 'InsertBeforeSelf', my totals row is getting overridden.
My question is, using openxml, how can I insert rows into the spreadsheet, causing the totals row to be be moved down each time a row is inserted?
Regards ...
Assuming you're using the SDK 2.0, I did something similiar by using this function:
private static Row CreateRow(Row refRow, SheetData sheetData)
{
uint rowIndex = refRow.RowIndex.Value;
uint newRowIndex;
var newRow = (Row)refRow.Clone();
/*IEnumerable<Row> rows = sheetData.Descendants<Row>().Where(r => r.RowIndex.Value >= rowIndex);
foreach (Row row in rows)
{
newRowIndex = System.Convert.ToUInt32(row.RowIndex.Value + 1);
foreach (Cell cell in row.Elements<Cell>())
{
string cellReference = cell.CellReference.Value;
cell.CellReference = new StringValue(cellReference.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
}
row.RowIndex = new UInt32Value(newRowIndex);
}*/
sheetData.InsertBefore(newRow, refRow);
return newRow;
}
I'm not sure how you were doing it with InsertBeforeSelf before, so maybe this isn't much of an improvement, but this has worked for me. I was thinking you could just use your totals row as the reference row. (The commented out part is for if you had rows after your reference row that you wanted to maintain. I made some modifications, but it mostly comes from this thread: http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/65c9ca1c-25d4-482d-8eb3-91a3512bb0ac)
Since it returns the new row, you can use that object then to edit the cell values with the data from the database. I hope this is at least somewhat helpful to anyone trying to do this...
[Can someone with more points please put this text as a comment for the M_R_H's Answer.]
The solution that M_R_H gave helped me, but introduces a new bug to the problem. If you use the given CreateRow method as-is, if any of the rows being moved/re-referenced have formulas the CalcChain.xml (in the package) will be broken.
I added the following code to the proposed CreateRow solution. It still doesn't fix the problem, because, I think this code is only fixing the currently-being-copied row reference:
if (cell.CellFormula != null) {
string cellFormula = cell.CellFormula.Text;
cell.CellFormula = new CellFormula(cellFormula.Replace(row.RowIndex.Value.ToString(), newRowIndex.ToString()));
}
What is the proper way to fix/update CalcChain.xml?
PS: SheetData can be gotten from your worksheet as:
worksheet.GetFirstChild<SheetData>();
You have to loop all rows and cells under the inserted row,change its rowindex and cellreference. I guess OpenXml not so smart that help you change index automatically.
static void InsertRow(string sheetName, WorkbookPart wbPart, uint rowIndex)
{
Sheet sheet = wbPart.Workbook.Descendants<Sheet>().Where((s) => s.Name == sheetName).FirstOrDefault();
if (sheet != null)
{
Worksheet ws = ((WorksheetPart)(wbPart.GetPartById(sheet.Id))).Worksheet;
SheetData sheetData = ws.WorksheetPart.Worksheet.GetFirstChild<SheetData>();
Row refRow = GetRow(sheetData, rowIndex);
++rowIndex;
Cell cell1 = new Cell() { CellReference = "A" + rowIndex };
CellValue cellValue1 = new CellValue();
cellValue1.Text = "";
cell1.Append(cellValue1);
Row newRow = new Row()
{
RowIndex = rowIndex
};
newRow.Append(cell1);
for (int i = (int)rowIndex; i <= sheetData.Elements<Row>().Count(); i++)
{
var row = sheetData.Elements<Row>().Where(r => r.RowIndex.Value == i).FirstOrDefault();
row.RowIndex++;
foreach (Cell c in row.Elements<Cell>())
{
string refer = c.CellReference.Value;
int num = Convert.ToInt32(Regex.Replace(refer, #"[^\d]*", ""));
num++;
string letters = Regex.Replace(refer, #"[^A-Z]*", "");
c.CellReference.Value = letters + num;
}
}
sheetData.InsertAfter(newRow, refRow);
//ws.Save();
}
}
static Row GetRow(SheetData wsData, UInt32 rowIndex)
{
var row = wsData.Elements<Row>().
Where(r => r.RowIndex.Value == rowIndex).FirstOrDefault();
if (row == null)
{
row = new Row();
row.RowIndex = rowIndex;
wsData.Append(row);
}
return row;
}
Above solution got from:How to insert the row in exisiting template in open xml. There is a clear explanation might help you a lot.