How to make a customized GridView that is completely user defined - c#

I have a GridView:
On Button_Click
I want the first column of my GridView with the items of ListBox1 and 2nd column with the EDIT link and from 3rd column on wards I want the headers as the items of ListBox2.
So far I am able to achieve EDIT link in the 2nd column and from 3rd column on wards the headers of the GridView with ListBox2 items.
Now I want ListBox1 items as the first column of my GridView. I have attached an image with show what exactly I want and what I have achieved so far.
Kindly help me on. Thank you.
The .cs code I have designed is:
DataTable dt = new DataTable();
DataRow rw = default(DataRow);
for (int i = 0; i < ListBox3.Items.Count; i++)
{ dt.Columns.Add(ListBox3.Items[i].ToString(),System.Type.GetType("System.String"));
}
for (int j = 0; j < count; j++)
{
rw = dt.NewRow();
for (int i = 0; i < ListBox3.Items.Count; i++)
{
rw[ListBox3.Items[i].ToString()] = " ";
}
dt.Rows.Add(rw);
}
GridView2.DataSource = dt;
GridView2.DataBind();
The asp code for GridView is :
<Columns>
<asp:TemplateField HeaderText="Locations">
<ItemTemplate>
<asp:Label ID="Lab1" runat="server"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>

First create a event of your gridview_RowDataBound
and change value of your label
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lbl1= ((Label)e.Row.FindControl("Lab1"));
lbl1.text = ListBox1.items[e.Row.RowIndex].ToString();
}
}

Related

Change forecolor of gridview cell based on condition in asp.net c#

I need to change the gridview cell color to red if the value is <=0. I have tried the below piece of code and it doesn't take the cell value of each row.
How can I get each cell value of gridview.
Code:
if (e.Row.RowType == DataControlRowType.DataRow)
{
foreach (GridViewRow row in GridView1.Rows)
{
for (int i = 0; i < GridView1.Columns.Count; i++)
{
TableCell cell = row.Cells[i];
int quantity = int.Parse(cell.Text);
if (quantity <= 0)
{
cell.ForeColor = Color.Red;
}
}
}
}
If you want to change the foreground color or access the text, you should use itemtemplate instead of boundField.
<asp:TemplateField HeaderText="Status" ControlStyle-Width="75px" >
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ParentID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
and you can bind this variable like
protected void GridView1_DataBound(object sender, EventArgs e)
{
for (int i =0 ; i <= GridView1.Rows.Count -1 ;i++)
{
Label lblparent = (Label)GridView1.Rows[i].FindControl("Label1");
if (lblparent.Text == "1")
{
GridView1.Rows[i].Cells[6].BackColor = Color.Yellow;
lblparent.ForeColor = Color.Black;
}
else
{
GridView1.Rows[i].Cells[6].BackColor = Color.Green;
lblparent.ForeColor = Color.Yellow;
}
}
}
for more help check this
https://forums.asp.net/t/1747819.aspx?how+to+change+gridview+cell+color+based+on+cell+item
Your code worked for me. I put it into DataBound event:
protected void GridView1_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow row in GridView1.Rows)
{
for (int i = 0; i < GridView1.Columns.Count; i++)
{
TableCell cell = row.Cells[i];
int quantity = int.Parse(cell.Text);
if (quantity <= 0)
{
cell.ForeColor = System.Drawing.Color.Red;
}
}
}
}
My gridview code is:
<asp:GridView ID="GridView1" HeaderStyle-BackColor="#3AC0F2" HeaderStyle-ForeColor="White" runat="server" AutoGenerateColumns="false" OnDataBound="GridView1_DataBound">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" ItemStyle-Width="30" />
<asp:BoundField DataField="quantity" HeaderText="Quantity" ItemStyle-Width="150" />
<asp:BoundField DataField="number" HeaderText="number" ItemStyle-Width="150" />
</Columns>
</asp:GridView>
I think the key is OnDataBound="GridView1_DataBound" on your GridView1
This is the code you are looking for :
Label lblInfo = (Label)gvVisa_Mofa.Rows[i].FindControl("lblInfo");
if (lblInfo.Text <= "0")
{
gvVisa_Mofa.Rows[i].BackColor = System.Drawing.ColorTranslator.FromHtml("#EDA3A3");
}
another method :
if (e.Row.RowType == DataControlRowType.DataRow)
{
If(Condition True)
{
e.Row.BackColor = Drawing.Color.Red
}
}

Two Columns with same header text in gridview in c#

I am having a gridview in which I don't want to display Header Text for two columns and two columns should have same header name (INFA). Gridview Looks Like:
<asp:GridView ID="GridView6" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="DayOfWeek" HeaderText="" ItemStyle-Width="30" />
<asp:BoundField DataField="DateOfMonth" HeaderText="" ItemStyle-Width="30" />
<asp:BoundField DataField="Emp_Name" HeaderText="INFA" ItemStyle-Width="30" />
<asp:BoundField DataField="Group_Name" HeaderText="INFA" ItemStyle-Width="30" />
<asp:BoundField DataField="Emp_Id" HeaderText="Mainframe" ItemStyle-Width="30" />
</Columns>
</asp:GridView>
I need to flip this gridview and make rows into columns and columns into rows. The logic was working fine when I had different names in Header Text for all DataFields. But in my requirement I don't need a Header text for two columns and two columns must have same header text (As shown above in Gridview). When I run my logic with no column name as shown above I get this error:
Exception Details: System.Data.DuplicateNameException: A column named ' ' already belongs to this DataTable.
My logic is:
protected void btnConvert_Data()
{
System.Data.DataTable dt = new System.Data.DataTable("GridView_Data");
foreach (TableCell cell in GridView6.HeaderRow.Cells)
{
if (cell.Text == "")
{
dt.Columns.Add("");
}
else
{
dt.Columns.Add(cell.Text);
}
}
dt.Rows.Add("IST Hours");
//dt.Rows.Add("8:45AM-6PM");
foreach (GridViewRow row in GridView6.Rows)
{
dt.Rows.Add();
for (int i = 0; i < row.Cells.Count; i++)
{
dt.Rows[dt.Rows.Count - 1][i] = row.Cells[i].Text;
}
}
gvColumnsAsRows.DataSource = FlipDataTable(dt);
gvColumnsAsRows.DataBind();
gvColumnsAsRows.HeaderRow.Visible = false;
}
To flip rows into columns and vice versa:
public static System.Data.DataTable FlipDataTable(System.Data.DataTable dt)
{
System.Data.DataTable table = new System.Data.DataTable();
//Get all the rows and change into columns
for (int i = 0; i <= dt.Rows.Count; i++)
{
table.Columns.Add(Convert.ToString(i));
}
DataRow dr;
//get all the columns and make it as rows
for (int j = 0; j < dt.Columns.Count; j++)
{
dr = table.NewRow();
dr[0] = dt.Columns[j].ToString();
for (int k = 1; k <= dt.Rows.Count; k++)
dr[k] = dt.Rows[k - 1][j];
table.Rows.Add(dr);
}
return table;
}
I am getting the above mentioned error in btnConvert_Data() on line dt.Columns.Add(cell.Text);. Can anyone please help me with this issue?
My final Output when I flip the Gridview should look like this:
column header text and column name are different, which column name must be unique in a DataTable.
so for you instance, you can specify a different random name to the columns which have no column header text
and also, you need to detect if the Header is real string.Empty or something just looks like empty, in your case, the header text is never an empty value, it's
so your logic will never hit, i mean cell.Text=="" will always returns false
so here is the solution
foreach (TableCell cell in GridView6.HeaderRow.Cells)
{
if (cell.Text == " ")
{
dt.Columns.Add(Guid.NewGuid().ToString()); //just some random value, i use guid, you can use anything you like to keep it unique.
}
else
{
dt.Columns.Add(cell.Text);
}
}
You need to make sure that every column has a unique name. You can do that by checking if the column name exists and if so make it a unique one by adding the index to the column name.
for (int i = 0; i < GridView1.HeaderRow.Cells.Count; i++)
{
string cellText = GridView1.HeaderRow.Cells[i].Text;
//check if the column name exists and if so make it unique
if (dt.Columns.Contains(cellText))
{
dt.Columns.Add(cellText + "_" + i);
}
else
{
dt.Columns.Add(cellText);
}
}

GridView: OnRowDatabound HeaderText Equals to ColumnText with AutoGenerateColumn True c# Asp.net

I have a gridview with first columns is same as headers i.e. same value with autogeneratecolumns as true, what i need to do in RowDatabound if HeaderText Equals to Intersect of the first Column text, Change the color to Yellow. Please see the attached image of the Desireed Gridview Output.
GridViewDesiredOutput
HTML
<asp:GridView ID="GvSamples" OnRowDataBound="GvSamples_RowDataBound" runat="server" AutoGenerateColumns="True">
C#
public void BindSamplesGrid()
{
DataTable _dt = new DataTable();
_dt = BL.GetSample(_conn);
GvSamples.DataSource = _dt;
GvSamples.DataBind();
}
protected void GvSamples_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count; i++)
{
if (e.Row.Cells[i].Text == e.Row.Cells[i].Text)
e.Row.Cells[i].Text = e.Row.Cells[i].Text.Replace("_", " ");
}
}
}
I am using asp.net C# Gridview.
Thank you
There are a couple of issues with your code. First of all you can only access the header row in DataControlRowType.Header, so coloring the cells as desired must be done in DataControlRowType.DataRow.
Next you are evaluating exactly the same value, so it will always be true: e.Row.Cells[i].Text == e.Row.Cells[i].Text, although this does not seem to do much except replace a _, which has nothing to do with getting the cell color to be yellow.
The below snippet does what you need. It gets the current row number and colors the correct cell yellow.
protected void GvSamples_RowDataBound(object sender, GridViewRowEventArgs e)
{
//check if the row is a datarow
if (e.Row.RowType == DataControlRowType.DataRow)
{
//get the current row number
int rowIndex = e.Row.RowIndex;
//check if the rownumber does not exceed the column count
if (rowIndex < e.Row.Cells.Count - 1)
{
//make the cell yellow
e.Row.Cells[rowIndex + 1].BackColor = Color.Yellow;
}
}
}

GridView Footer row is null

Footer is set to visible and I can see it's being created. However when total (table sums) are passed over to it, there's error indicating GridView2.FooterRow is null...
totTable refers to a DataTable carrying totals.
aspx:
ShowHeader="true" ShowFooter="true" FooterStyle-CssClass="FooterStyle"
cs:
DataRow dr = totTable.Rows[0];
foreach (DataControlField col in GridView2.Columns)
{
foreach (DataColumn dc in totTable.Columns)
{
int i = GridView2.Columns.IndexOf(col);
GridView2.FooterRow.Cells[i].Text = dr[i].ToString();
}
}
What's the root cause behind this?
use following code after binding gridview:
public void CountGrandTotal()
{
int sum = 0;
for (int i = 0; i <grdproduct.Rows.Count ; i++)
{
Label lblprice = (Label)grdproduct.Rows[i].FindControl("Label5");
sum += int.Parse(lblprice.Text);
}
Label lblgtotal = (Label)grdproduct.FooterRow.FindControl("Label7");
lblgtotal.Text = sum.ToString();
Add the footer on the OnLoad method of the GridView.
<asp:GridView ID="Gv"
runat="server"
ShowFooter="true"
OnLoad="Gv_Load">

Im trying to create an ASP.NET table using a for loop for a set of hyperlinks

I have list of hyperlinks which i want to use to create a 2x* table (* is number of hyperlinks)
Here is my code...
for (int rows = 0; rows < hlist.Count; rows++) //Create rows for the number of hyperlinks, so i will always have a spare row.
{
TableRow row = new TableRow(); // Create the new rows
table.Rows.Add(row); //Add rows to the table
for (int cells = 0; cells < 2; cells++)
{
TableCell cell = new TableCell();
for(int h = 0; h < hlist.Count; h++)
cell.Controls.Add(hlist[h]);
row.Cells.Add(cell);
}
}
All this does is list all my hyperlinks in a single column table, with a new row for each hyperlink!
Any help would be appreciated!!
Thanks
Assuming that you want to create a table that shows two hyperlinks per row, you could try the following code:
for (int i = 0; i < hlist.Count; i += 2)
{
TableRow row = new TableRow(); // Create the new rows
table.Rows.Add(row);
for (int j = i; j < Math.Min(i + 2, hlist.Count); j++)
{
TableCell cell = new TableCell();
cell.Controls.Add(hlist[j]);
row.Controls.Add(cell);
}
}
However, using dynamically added controls in ASP.NET is complex if you want them to react on events. So I'd propose to check whether you could change your approach so that you can use a Repeater instead. In order to do so, you'd first have to change your data model, e.g. to a list of Pair objects that contain two URLs, e.g.:
public void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
IEnumerable<Uri> uris = GetUris();
List<Tuple<Uri, Uri>> pairs = new List<Tuple<Uri, Uri>>();
for (int i = 0; i < uris.Count; i += 2)
{
var uri1 = uris[i];
var uri2 = i + 1 < uris.Count ? uris[i + 1] : null;
pairs.Add(new Tuple<Uri, Uri>(uri1, uri2));
}
rpt.DataSource = pairs;
rpt.DataBind();
}
}
If your URLs are not compatible with a Uri (maybe they contain a leading ~), you can also use strings instead of Uri.
The markup for your the Repeater would look similar to this:
<asp:Repeater ID="rpt" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:HyperLink runat="server" Text="Link 1"
NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "Item1") %>' />
</td>
<td>
<asp:HyperLink runat="server" Text="Link 1"
NavigateUrl='<%# DataBinder.Eval(Container.DataItem, "Item2") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>

Categories

Resources