Gridview - Loop through multiple header rows - c#

In a console app, a gridview is created dynamically.
GridView gv = new GridView();
gv.AutoGenerateColumns = false;
for (int i = 0; i < dt.Columns.Count; i++)
{
BoundField boundfield = new BoundField();
boundfield.DataField = dt.Columns[i].ColumnName.ToString();
boundfield.HeaderText = arr[i].ToString();// dt.Columns[i].ColumnName.ToString();
gv.Columns.Add(boundfield);
}
Then, two more header rows are added. Here is a partial of one row:
GridViewRow HeaderGridRow = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell = new TableCell();
HeaderCell.Text = "";
HeaderCell.ColumnSpan = 4;
HeaderGridRow.Cells.Add(HeaderCell);
//more header cells added then another row here
gv.DataSource = dt;
gv.DataBind();
gv.Controls[0].Controls.AddAt(0, HeaderGridRow);
Using a foreach loop, adjusting separate cell borders not in the header is done:
foreach (GridViewRow row in gv.Rows)
{
TableCell tCell = row.Cells[0];
tCell.Attributes["style"] = "border-right:0";
}
I have been trying to find a way to loop through the header rows and adjust some borders on the cells.
Tried using foreach (GridViewRow row in gv.HeaderRow) but gv.HeaderRow does not have a public definition for GetEnumerator.
Tried for(int i = 0; i < gv.HeaderRow.Cells.Count; i++) but that doesn't seem to work either.
Anyone have any suggestions?
Thanks!!

Try this
GridViewRow headerRow = gv.HeaderRow;
TableCell hCell = headerRow.Cells[0];
hCell.Attributes["style"] = "border-right:0";
Hope it helps

Related

How to filter Datagridview That Fill By Webrequest And Dont Have Datasource?

I created a Winforms C# application, and then filled a Datagridview in form load with a web request from website database (database can't control remotely).
In the form load I disable some columns. Now I want to filter datagridview by columns that the client write in textbox.
This is my form load code to fill Datagridview:
MyWebRequest Showrequest = new MyWebRequest("https://websitename.com/connector.php", "POST","metod=showform&Table=Propertys");
string shreqres = Showrequest.GetResponse();
string[] propertytablerows = shreqres.Split('♣');
for (int i = 0; i < propertytablerows.Length; i++)
{
string propertytablerows1 = propertytablerows[i];
string[] propertytablerow = propertytablerows1.Split(',');
propertydatagrid.Rows.Add(propertytablerow);
}
int[] hidecolumns = {3,10,11,12,14,16,19,20,21,25,26,27,28,29,31,35,36,37,38,39,40,41,42,43,44,45,46,47,50,54,55,56,57,58,59,60,61,62,63,64,65,66,48,67,68,69,72,73,74,75,76,79,80};
for (int i=0;i<hidecolumns.Length;i++)
{
propertydatagrid.Columns[hidecolumns[i]].Visible = false;
}
And my code in textbox textchange to filter datagridview:
DataTable dt = new DataTable();
foreach (DataGridViewColumn col in propertydatagrid.Columns)
{
dt.Columns.Add(col.Name);
}
foreach (DataGridViewRow row in propertydatagrid.Rows)
{
DataRow dRow = dt.NewRow();
foreach (DataGridViewCell cell in row.Cells)
{
dRow[cell.ColumnIndex] = cell.Value;
}
dt.Rows.Add(dRow);
}
propertydatagrid.DataSource = dt;
DataView dv = dt.DefaultView;
dv.RowFilter = "Owner LIKE '" + owner.Text + "%'";
propertydatagrid.DataSource = dv;
propertydatagrid.Refresh();
After loading form, there is no problem and datagridview fill and some columns hidden but when I write in textbox program crashed.

Bug in adding rows to table on the fly

i try adding rows to table on the fly from DataBase but its always the last row that appears only where am i wrong ?
TableCell pNameCell = new TableCell();
TableCell pDescCell = new TableCell();
TableCell pPriceCell = new TableCell();
TableCell pStockCell = new TableCell();
TableCell buyProduct = new TableCell();
HyperLink hl = new HyperLink();
//ds is DataSet
foreach (DataRow dRow in ds.Tables[0].Rows)
{
TableRow row = new TableRow();
pNameCell.Text = dRow["name"].ToString();
row.Cells.Add(pNameCell);
pDescCell.Text = dRow["description"].ToString();
row.Cells.Add(pDescCell);
pPriceCell.Text = dRow["price"].ToString();
row.Cells.Add(pPriceCell);
pStockCell.Text = dRow["Qty"].ToString();
row.Cells.Add(pStockCell);
hl.Text = "Add To Cart";
hl.NavigateUrl = "BuyProduct.aspx?id="+ dRow["pro_id"].ToString();
hl.CssClass = "btn btn-primary";
buyProduct.Controls.Add(hl);
row.Cells.Add(buyProduct);
//TProducts is asp:table ID
TProducts.Rows.Add(row);
}
it should show all the data rows in able
Your table cells are not unique to each iteration of the loop. When you add a cell variable to a row, it maintains a reference to that variable, not a copy. So then in the next iteration of the loop you overwrite the cell variable with the value from the new row, this will also update all the references to that cell.
To fix it, simply move the table cell declarations inside the loop, then their scope will be limited to that iteration, and new variables will be created each time you loop - just like the table row variable already is, in fact:
//ds is DataSet
foreach (DataRow dRow in ds.Tables[0].Rows)
{
TableCell pNameCell = new TableCell();
TableCell pDescCell = new TableCell();
TableCell pPriceCell = new TableCell();
TableCell pStockCell = new TableCell();
TableCell buyProduct = new TableCell();
HyperLink hl = new HyperLink();
TableRow row = new TableRow();
pNameCell.Text = dRow["name"].ToString();
row.Cells.Add(pNameCell);
pDescCell.Text = dRow["description"].ToString();
row.Cells.Add(pDescCell);
pPriceCell.Text = dRow["price"].ToString();
row.Cells.Add(pPriceCell);
pStockCell.Text = dRow["Qty"].ToString();
row.Cells.Add(pStockCell);
hl.Text = "Add To Cart";
hl.NavigateUrl = "BuyProduct.aspx?id="+ dRow["pro_id"].ToString();
hl.CssClass = "btn btn-primary";
buyProduct.Controls.Add(hl);
row.Cells.Add(buyProduct);
//TProducts is table ID
TProducts.Rows.Add(row);
}

Show Total Row In Grid Each Time Name Changes

I am attempting to display a grid on my page and each time the name in the grid changes display a Total for that name. However, I keep getting a error of Object not set to instance of an object This is my syntax I am trying, can someone take a look and fill me in on what I am doing wrong?
<asp:GridView ID="gvTest" runat="server" OnDataBound = "gvODB" OnRowCreated = "gvORC" >
<Columns>
<asp:BoundField DataField="" HeaderText="userID"></asp:BoundField>
<asp:BoundField DataField="employeename" HeaderText="Name"></asp:BoundField>
<asp:BoundField DataField="hoursworked" HeaderText="Daily Hours"></asp:BoundField>
</Columns>
</asp:GridView>
private int currentId = 0;
private decimal subTotal = 0;
private decimal total = 0;
private int subTotalRowIndex = 0;
protected void gvORC(object sender, GridViewRowEventArgs e)
{
DataTable dt = new DataTable();
subTotal = 0;
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
dt = (e.Row.DataItem as DataRowView).DataView.Table;
int userID = Convert.ToInt32(dt.Rows[e.Row.RowIndex]["userID"]);
total += Convert.ToDecimal(dt.Rows[e.Row.RowIndex]["hoursworked"]);
if (userID != currentId)
{
if (e.Row.RowIndex > 0)
{
for (int i = subTotalRowIndex; i < e.Row.RowIndex; i++)
{
subTotal += Convert.ToDecimal(gvTest.Rows[i].Cells[2].Text);
}
this.AddTotalRow("Total", subTotal.ToString("N2"));
subTotalRowIndex = e.Row.RowIndex;
}
currentId = userID;
}
}
}
catch (Exception exception)
{
throw exception;
}
}
protected void AddTotalRow(string labelText, string value)
{
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
row.BackColor = ColorTranslator.FromHtml("#F9F9F9");
row.Cells.AddRange(new TableCell[3] { new TableCell (), //Empty Cell
new TableCell { Text = labelText, HorizontalAlign = HorizontalAlign.Right},
new TableCell { Text = value, HorizontalAlign = HorizontalAlign.Right } });
gvTest.Controls[0].Controls.Add(row);
}
EDIT --
The grid will return a userid, username and hours worked. And I want a total to be displayed for each individual username returned. Something like so
userid name hours
1646 Red 16
1646 Red 8
Total 24
1812 Blue 6
1812 Blue 8
Total 14
Now a userid, name and hours will ALWAYS be returned, the only time a null value would be returned is when all results have been added to the grid.
The idea is to generate the html that will display your simple "report". There are any number of ways to do this. If the data is read only then using a Grid is less appropriate than just building a table or set of divs, etc. You can look into the Repeater or ListView but here I demonstrate a simple table element:
The aspx markup that has a simple asp:Table with runat server:
<%# Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:Table runat="server" ID="usertbl" border="1">
</asp:Table>
</asp:Content>
The Code behind:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Contrived Data table just because I need some data to demonstrate.
//I assume you are or can acquire a DataTable with your current solution.
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("UserID", typeof(int)));
dt.Columns.Add(new DataColumn("UserName", typeof(string)));
dt.Columns.Add(new DataColumn("Hours", typeof(int)));
DataRow row = dt.NewRow();
row[0] = 1646;
row[1] = "Red";
row[2] = 16;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1646;
row[1] = "Red";
row[2] = 8;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1812;
row[1] = "Blue";
row[2] = 6;
dt.Rows.Add(row);
row = dt.NewRow();
row[0] = 1812;
row[1] = "Blue";
row[2] = 14;
dt.Rows.Add(row);
//Simplify accumualtor logic by grouping on Userid
var users = dt.AsEnumerable().GroupBy(u => u[0]);
//For each group (each user id)
foreach (var item in users)
{
//adds the user hours
int accumulator = 0;
//For each set or rows in group
foreach (var dr in item)
{
accumulator += int.Parse(dr[2].ToString());
//Create a table row
TableRow tr = new TableRow();
//Add the cells to the table row
TableCell userIdCell = new TableCell();
userIdCell.Text = item.Key.ToString();
tr.Cells.Add(userIdCell);
TableCell userNameCell = new TableCell();
userNameCell.Text = dr[1].ToString();
tr.Cells.Add(userNameCell);
TableCell hoursCell = new TableCell();
hoursCell.Text = dr[2].ToString();
tr.Cells.Add(hoursCell);
//Add the row to the table
usertbl.Rows.Add(tr);
}
//create summary row
TableRow totalRow = new TableRow();
//Skip a cells
totalRow.Cells.Add(new TableCell());
totalRow.Cells.Add(new TableCell());
//total cell
TableCell userTotalCell = new TableCell();
userTotalCell.Text = accumulator.ToString();
totalRow.Cells.Add(userTotalCell);
//Finally add the row
usertbl.Rows.Add(totalRow);
}
}
}
}
and finally the result:

How to programmatically add rows to DataGrid in C#?

So as the title states, I'm trying to add rows to a DataGrid programmatically using C# but I can't seem to make it work. This is what I have so far.
// I have a DataGrid declared as dg in the XAML
foreach (string s in array) {
int index = 0;
DataGridRow dgRow = new DataGridRow();
foreach (DataGridColumn dgColumn in columns)
{
// Trying to add Text to dgRow here but IDK how
index++;
}
}
I've been googling around and the closest I got to adding anything was to use {column = value} but it just throws me an error. Really out of ideas now though :\
Here's you can do it better way by binding a source to datagridview
// Creating DataSource here as datatable having two columns
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name");
// Adding the rows in datatable
for (int iCount = 1; iCount < 6; iCount++)
{
var row = dt.NewRow();
row["ID"] = iCount;
row["Name"] = "Name " + iCount;
dt.Rows.AddRow(row);
}
DataGridView dgv = new DataGridView();
// Set AutoGenerateColumns true to generate columns as per datasource.
dgv.AutoGenerateColumns = true;
// Finally bind the datasource to datagridview.
dgv.DataSource = dt;
In Case you are using WPF DataGrid
you can bind it like this way-
dgv.DataContext = employeeData.DefaultView;
and in
XAML
<DataGrid Name="dgv" ItemsSource="{Binding}">
//create datatable and columns,
DataTable dtable = new DataTable();
dtable.Columns.Add(new DataColumn("Column 1"));
dtable.Columns.Add(new DataColumn("Column 2"));
//simple way create object for rowvalues here i have given only 2 add as per your requirement
object[] RowValues = { "", "" };
//assign values into row object
RowValues[0] = "your value 1";
RowValues[1] = "your value 2";
//create new data row
DataRow dRow;
dRow = dtable.Rows.Add(RowValues);
dtable.AcceptChanges();
//now bind datatable to gridview...
gridview.datasource=dbtable;
gridview.databind();
Regards
did you try?:
int n=5; // number of rows you want to add
dataGridView1.Rows.Add(n);
// you can add (names of the rows) if you have them in your array
//for(int i=0; i<n; i++)
//dataGridView1[0, i].Value = array[i];

Manually Add Row Values to Gridview

I have a winform app, where in i have a grid view that is supposed to search data from database and display to a gridview.
here is my code to create columns and add row values to it..
while (dr.Read())
{
DataGridViewColumn ad = new DataGridViewColumn();
DataGridViewCell cell = new DataGridViewTextBoxCell(); //Specify which type of cell in this column
ad.CellTemplate = cell;
ad.HeaderText = "Serial No";
ad.Name = "Serial No";
ad.Visible = true;
dataGridView2.Columns.Add(ad);
DataGridViewColumn ad1 = new DataGridViewColumn();
DataGridViewCell cell1 = new DataGridViewTextBoxCell(); //Specify which type of cell in this column
ad1.CellTemplate = cell1;
ad1.HeaderText = "Enrollment No.";
ad1.Name = "Enrollment No.";
ad1.Visible = true;
dataGridView2.Columns.Add(ad1);
DataGridViewColumn ad2 = new DataGridViewColumn();
DataGridViewCell cell2 = new DataGridViewTextBoxCell(); //Specify which type of cell in this column
ad2.CellTemplate = cell1;
ad2.HeaderText = "Student Name";
ad2.Name = "Studen Name";
ad2.Visible = true;
dataGridView2.Columns.Add(ad2);
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dataGridView2);
row.Cells[0].Value = dr.GetValue(0).ToString();
row.Cells[1].Value = dr.GetValue(1).ToString();
row.Cells[2].Value = dr.GetValue(2).ToString();
//row.Cells[3].Value = dr.GetValue(3).ToString();
//row.Cells[4].Value = dr.GetValue(4).ToString();
//row.Cells[5].Value = dr.GetValue(5).ToString();
dataGridView1.Rows.Add(row);
i++;
}
i have created 3 columns and i'm trying to store three values from database to the three corresponding cells.
but while executing i get the following error
No row can be added to a DataGridView control that does not have columns. Columns must be added first.
what am i doing wrong?
Please let me know. thanks in advance for all your help...
Problem : You are Adding the columns to dataGridView2 but finally you are trying to add the rows to dataGridView1.
Solution : if your intention isto add the rows to the dataGridView2 replace the follwing statement
Replace This:
dataGridView1.Rows.Add(row);
With This:
dataGridView2.Rows.Add(row);

Categories

Resources