Deleting Grid View Row data wrongly Windows Form My Code Attached? - c#

i am trying to delete grid view data as i am filling grid like,
public void FillCompanyInfo()
{
DataTable dtCompanyInfo = new DataTable();
dtCompanyInfo = objFunctions.GetCompanyInfo();
if(dtCompanyInfo.Rows.Count>0)
{
dgvCompany.DataSource = dtCompanyInfo;
}
if (dtCompanyInfo.Rows.Count > 0)
{
if (this.dgvCompany.Columns.Count == 8)
{
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "";
checkColumn.HeaderText = "Select";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values\\
dgvCompany.Columns.Add(checkColumn);
}
}
}
After filling grid i click on grid row and click delete button as,
private void btn_Delete_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow r in dgvCompany.Rows)
{
if (Convert.ToBoolean(r.Cells[8].Value)) //cells[4] CONTAINS CHECKBOX COLUMN
{
string strId = r.Cells[1].Value.ToString(); //cells[0] CONTAINS EMPIDCOLUMN
objFunctions.DeleteCompany(strId);
}
}
FillCompanyInfo();
}
But it delete the data wrongly in my grid view i get fields numeric and string from 0 to 6 and chk box at 7th place while after binding data to grid i also attach one more column at 8 place may me it is due to some that reason ?
while debugging i suddenly notice at this place,
foreach (DataGridViewRow r in dgvCompany.Rows)
that grid view have column in this manner chk box at zero position then seven fild and again then chk box at 8 place how it change the order ?
hopes for your suggestion thanks in advance

You need to clear the grid view data source before bind it.Please Refer this link to clear grid view. try this code
Datagridview remove all columns
public void FillCompanyInfo()
{
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
dtCompanyInfo = GetCompanyInfo();
if (dtCompanyInfo.Rows.Count > 0)
{
dataGridView1.DataSource = dtCompanyInfo;
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "";
checkColumn.HeaderText = "Select";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values\\
dataGridView1.Columns.Add(checkColumn);
}
}

Related

How to add multiple TextBox follow by DataGridView.Columns.Count and column data.TQ

//...
{
public Form1()
{
InitializeComponent();
LoadData();
textBoxFill();
}
private void LoadData()
{
SqlConnection SCConnect = new SqlConnection("Server=localhost;Initial Catalog=T8;Integrated Security=SSPI;");
SCConnect.Open();
StringBuilder SBBuilder = new StringBuilder("Select * from Table8");
SqlDataAdapter SDA = new SqlDataAdapter(SBBuilder.ToString(), SCConnect);
SqlCommandBuilder SCB = new SqlCommandBuilder(SDA);
DataTable DT = new DataTable();
SDA.Fill(DT);
dataGridView1.DataSource = DT;
}
private void textBoxFill()
{
TextBox TB = new TextBox();
int A = 1;
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
panel1.Controls.Add(TB);
TB.Location = new Point(10, (A * 20));
TB.Top = A * 28;
TB.Size = new Size(200, 50);
TB.Margin = new Padding(10, 10, 10, 10);
}
A = A + 1;
}
}
How do I add multiple TextBox follow by DataGridView.Columns.Count and
each TextBox to fill in each DataGridView columns data.TQ?
I am guessing after looking at the previous duplicate post, that this may be what you are looking for. It may help you if you explained the overall picture as this seems like on odd thing to do since the data is already in the grid and the user can edit it, I am not sure why you would do this data “duplication” in the panel.
However, it does appear you want to have the textboxes correspond to the currently “selected” row in the grid. Such that there will be one textbox for each column in the grid. Initially, you do know how many columns the data may contain. Therefore, you need to dynamically create the textbox’s in the panel.
One approach to “bind” each textbox to a column of the currently selected row in the grid may be accomplished by “binding” each textbox to a particular column in the DataTable that is used as the DataSource to the grid. Each textbox has a property called…DataBindings. This property will allow you to “bind” the textbox to a particular column in the DataTable. Below is an example.
To help, given we have the data, I suggest a method AddTextBoxesToPanel(DataTable dt) … that takes a DataTable and loops through the columns of that table and creates a textbox for each column AND adds the “binding” for that column to that textbox. With this approach, no extra code will be necessary to fill the text boxes when the user selects different rows.
private void AddTextBoxesToPanel(DataTable dt) {
panel1.Controls.Clear();
panel1.AutoScroll = true;
panel1.AutoScrollMinSize = new Size(0, (dt.Columns.Count * 23) + 15);
TextBox curTB;
int y = 10;
foreach (DataColumn col in dt.Columns) {
curTB = GetTextBox(10, y);
curTB.DataBindings.Add(new Binding("Text", dt, col.ColumnName));
panel1.Controls.Add(curTB);
y += 23;
}
}
Above, we assume this may be called more than once and need to “clear” any previous textboxs in the panel. Set the panel to be scrollable, then start the loop through the columns to add the textboxes to the panel. The GetTextBox method (below) simply gets a new TextBox with the desired location. Lastly, we set the DataBinding for “that” textbox to point to “that” column. curTB.DataBindings.Add(new Binding("Text", dt, col.ColumnName));
private TextBox GetTextBox(int xLoc, int yLoc) {
TextBox TB = new TextBox {
Text = "",
Location = new Point(xLoc, yLoc),
Size = new Size(150, 50),
Margin = new Padding(10),
Anchor = AnchorStyles.Left
};
return TB;
}
Below is a complete example using the above method. The Forms Load method to fill a DataTable with 10 columns and 20 rows, then use that DataTable as a DataSource to the grid. Then call the method above to set the textboxes into the panel.
private void Form1_Load(object sender, EventArgs e) {
FillGrid(10, 20);
AddTextBoxesToPanel((DataTable)dataGridView1.DataSource);
}
A method to generate some data for testing.
private void FillGrid(int totalColumns, int totRows) {
DataTable dt = new DataTable();
// add columns
for (int i = 0; i < totalColumns; i++) {
dt.Columns.Add("Col" + i, typeof(string));
}
// add rows
object[] data = new object[totalColumns];
for (int row = 0; row < totRows; row++) {
for (int col = 0; col < totalColumns; col++) {
data[col] = "Col" + col + "Row" + row;
}
dt.Rows.Add(data);
}
dataGridView1.DataSource = dt;
}
Hope this helps.

Equivalent WinForm DataGridView code to WPF DataGrid

I have a data in DataGrid with n Rows, and the DataGrid is ReadOnly. Now my goal is to when I select any row or rows and then press EDIT Button then all the selected rows only becomes ReadOnly = false. so that I want to edit some data in selected row(s). After this when I press the update button then only the selected rows are updated using EntityFramework.
I done this task in WinForm DataGridView. Now I want the same thing in WPF DataGrid.
private void editCust_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
foreach (DataGridViewRow item in dataGridView1.SelectedRows)
{
for (int i = 1; i <= 3; i++)
{
item.Cells[i].ReadOnly = false;
}
}
}
else
{
MessageBox.Show("No Row Is Selected To Edit.");
}
}
private void updateCust_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
foreach (DataGridViewRow item in dataGridView1.SelectedRows)
{
cutable.Customer_Name = (string)item.Cells[1].Value;
cutable.Counter = int.Parse(Convert.ToString(item.Cells[2].Value));
cutable.Buying_Cost = float.Parse(Convert.ToString(item.Cells[3].Value));
for (int i = 1; i <= 3; i++)
{
item.Cells[i].ReadOnly = true;
}
}
db.SaveChanges();
MessageBox.Show("Record Is Update.");
}
else
{
MessageBox.Show("No Row Is Selected To Update.");
}
}
First convert DataGridView to DataTable then to DataGrid
For DataGridView to DataTable
Use this:
DataTable myDataTable=(DataTable)(myDataGridView.DataSource);
For more reference go through DataGridView to DataTable
Now for DataTable to DataGrid
Use this:
myDataGrid.ItemsSource=myDataTable.DefaultView;
myDataGrid.AutoGenerateColumns = true;
myDataGrid.CanUserAddRows = false;
For more reference go through DataTable to DataGrid
Comment for any query
UPDATE:
Try to create to your own code and logic, do not depend on direct solutions given by someone.
Well a similar issue I found in StackOverflow[Solved].
Refer to this question how to edit select row in datagrid in wpf
Hope it helps!

Setting the row style of a ComponentOne DataTree FlexGrid

I am using a ComponentOne DataTree that is a FlexGrid with child grids. The parent grid has 2 columns a 'Select' column which is a checkbox and another column that is read-only. The child grid has 5 columns. The first is a checkbox and the other 4 are readonly. The read-only columns appear gray by default. I set the DataTable columns that is the data source of the grids to ReadOnly. I want the non-header columns to have a background of white by default. Neither grid is updated.
I define the style as a member variable and create the style in the Initialize method:
C1.Win.C1FlexGrid.CellStyle defaultRowStyle;
private void InitializeControls()
{
txtWorkZone.Enabled = true;
txtWorkZone.Focus();
defaultRowStyle = c1flxdatatreeCasePick.Styles.Add("DefaultRowStyle");
defaultRowStyle.BackColor = Color.White;
}
This is the OwnerDrawCell method that sets it:
private void c1flxdatatreeCasePick_OwnerDrawCell(object sender, OwnerDrawCellEventArgs e)
{
C1FlexDataTree grid = sender as C1FlexDataTree;
if (grid == null || grid.DataSource == null)
return;
if(e.Row > 0)
grid.Rows[e.Row].Style = grid.Styles["DefaultRowStyle"];
//Get the child grid
C1FlexDataTree childGrid = grid.Rows[e.Row].UserData as C1FlexDataTree;
if (childGrid != null)
{
if(e.Row > 0)
childGrid.Rows[e.Row].Style = grid.Styles["DefaultRowStyle"];
}
}
Why won't the grids get the row style setting?
Thanks
Gloria
You wont be able to use OwnerDrawCell as you've expected here. After the FlexGrid is loaded on the form use the following snippet used to repaint readonly columns background:
C1.Win.C1FlexGrid.CellStyle cs;
cs = _flex.Cols[2].StyleDisplay;
cs.BackColor = Color.White;
cs = _flex.Cols[3].StyleDisplay;
cs.BackColor = Color.White;
If you need to change the background color of the Child Tables you have to change each child's properties individually. Use the following snippet to access the Child tables:
for (int row = 0; row < _flex.Rows.Count; row++)
{
C1FlexDataTree child = _flex.Rows[row].UserData as C1FlexDataTree;
if (child != null)
{
// Access Child Tables here
}
}
To make the child tables in my C1FlexDataTree read-only:
for (int row = 0; row < _flex.Rows.Count; row++)
{
C1FlexDataTree child = _flex.Rows[row].UserData as C1FlexDataTree;
if (child != null)
{
foreach (Column c in child.Cols)
{
c.AllowEditing = false;
}
}
}

Add multiple datagridview to form

I am developing a software and i need different form of a DataGridView.
I created them and inserted them into an array with this method:
private DataGridView[] cloneDataGridViews(int posCount, DataGridView dataGridView)
{
List<DataGridView> dataGridViewList = new List<DataGridView>();
for(int i=0;i<posCount;i++)
{
DataGridView dgv = new DataGridView();
dgv = dataGridView;
dataGridViewList.Add(dgv);
}
return dataGridViewList.ToArray();
}
And I am trying to show them with this code:
void GridViewSelectorLoad(object sender, System.EventArgs e)
{
this.AutoScroll = true;
int startY = 30;
for(int i=0;i<dataGridViewArray.Length;i++)
{
int height = dataGridViewArray[i].Height;
int posY = startY + 10 + i*height;
Panel pnl = new Panel();
pnl.Controls.Add(dataGridViewArray[i]);
dataGridViewArray[i].Parent = pnl;
pnl.Location = new Point(100,posY);
pnl.Name = "pnl"+i.ToString();
pnl.Height = dataGridViewArray[i].Height;
pnl.Width = dataGridViewArray[i].Width;
pnl.Parent = this;
this.Controls.Add(pnl);
}
}
But it shows just one datagridview, how can I show all of them?
What is wrong with that code?
A control can only have one parent, but you're trying to set the same DataGridView as a child of multiple Panels.
for(int i=0;i<posCount;i++)
{
DataGridView dgv = new DataGridView();
dgv = dataGridView; // not creating a new instance of DataGridView
dataGridViewList.Add(dgv);
}
Here's the relevant part of the Controls.Add() method that causes this behavior.
if (value.parent != null)
{
value.parent.Controls.Remove(value);
}
You've got a single instance of DataGridView that you add to each new Panel. Each time, it's Parent property is set to the latest Panel. Then when you try adding it to the next Panel, the code above removes it from the previous one.
If you create a new instance inside the loop, it works fine. You'll need to copy over those values from the existing DataGridView that you wish to have in each new DataGridView instance.
for(int i=0; i<posCount; i++)
{
DataGridView dgv
= new DataGridView
{
Name = dataGridView.Name,
DataSource = dataGridView.DataSource,
...
};
dataGridViewList.Add(dgv);
}
cloneDataGridViews is not cloning the datagrid, its adding the same instance multiple times:
dgv = dataGridView;
It has been pointed out that all you are copying in your code is the same old reference to the same DGV into each slot of your list. Instead you will have to copy both the column structure and the values of all cells like this:
public DataGridView cloneDataGridView(DataGridView oldDGV)
{
DataGridView newDGV = new DataGridView();
foreach (DataGridViewCell cell in oldDGV.Rows[0].Cells)
newDGV.Columns.Add(new DataGridViewColumn(cell));
newDGV.Rows.Add(oldDGV.Rows.Count);
for (int row = 0; row < oldDGV.Rows.Count; row++)
for (int col = 0; col < oldDGV.Columns.Count; col++)
newDGV[col, row].Value = oldDGV[col, row].Value;
return newDGV;
}
You could call it like this:
for(int i=0;i<posCount;i++)
{
DataGridView dgv = cloneDataGridView(dataGridView);
dataGridViewList.Add(dgv);
}
Note: This piece of code assumes that there is at least one row in the source DGV.

Loading, Updating and displaying Generic List Class

Goal in mind, the concept is kind of like a shopping cart, so as they add items to list(Detail) it keeps the items they are adding in memory.
This works when ever I first load the list(grid) and add more rows. But if I set the first row and set the item and price and then decide to add 3 more rows then
the info I had added gets deleted instead of keeping its values and just load more lines to the list which would repopulate the gridview.
In the past I have done this with datatables but I want to be able to move from that and use this List Class
Also I have it set as viewstate so I can use it through out my page.
private ListArDocumentdetail Detail
{
get
{
ListArDocumentdetail _detail = new ListArDocumentdetail();
if (ViewState["Detail"] != null)
{
_detail = (ListArDocumentdetail)ViewState["Detail"];
}
return _detail;
}
set
{
ViewState["Detail"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
//creates 2 rows to start off
CreateRows(2);
}
public void CreateRows(int rowstoadd)
{
int newtotalrows = Detail.Count + rowstoadd - 1;
for (int i = Detail.Count; i <= newtotalrows; i++)
{
ArDocumentdetail detail = new ArDocumentdetail();
detail.Lineid = i;
detail.Itemid = 0;
detail.Quantity = 1;
if (Detail.Count > 0)
Detail.Insert(Detail.Count, detail);
else
Detail.Add(detail);
Detail = Detail;
}
gvInvoiceDetail.DataSource = Detail;
gvInvoiceDetail.DataBind();
GridViewRow row = gvInvoiceDetail.Rows[gvInvoiceDetail.Rows.Count - 1];
ImageButton btnAdd = (ImageButton)row.FindControl("btnAdd");
btnAdd.Visible = true;
}
protected void ibAdd_Click(object sender, ImageClickEventArgs e)
{
//user can type in how many rows they want to add on to current amount of rows
//so since grid starts off at 2 and they type 3 the grid refreshes with 5 rows.
CreateRows(Convert.ToInt32(txtRows.Text));
}
protected void UpdateRow(object sender, EventArgs e)
{
ImageButton btnUpdate = sender as ImageButton;
GridViewRow row = btnUpdate.NamingContainer as GridViewRow;
TextBox txtPrice = (TextBox)row.FindControl("txtPrice");
TextBox txtQuantity = (TextBox)row.FindControl("txtQuantity");
DropDownList ddlDescription = (DropDownList)row.FindControl("ddlDescription");
int index = Detail.FindIndex(f => f.Lineid == row.RowIndex);
Detail[index].Itemid = Convert.ToInt32(ddlDescription.SelectedValue);
Detail[index].Price = Convert.ToDecimal(txtPrice.Text);
Detail[index].Subtotal = Convert.ToDecimal(Detail[index].Price * Convert.ToInt32(txtQuantity.Text));
}
I can suggest you the logic:
Push a list into viewstate say Viewstate["List"],
Let a user chose an item. Then List list = (List)Viewstate["List"];
Add the selected item to List list. i.e. list.Add(item);
Now push the item back to viewstate. Viewstate["list"] = list;
Bind it to grid or display it on page. Whatever you want.

Categories

Resources