How to add 2 rows in Gridview footer - c#

I am using a grid to display no of leads. In that I have to display Page wise total as well as Grand total. Is it possible to show it in 2 different rows in Footer?
Give me some suggestions. I have to add 8 columns in grid.

you can do this lots of ways, but one of them is to use TemplateField
here is format for your gridview (put your content in the cells)
...
<Columns>
<asp:TemplateField>
<FooterTemplate>
<table width="100%">
<tr><td><asp:Literal runat="server" ID="ltField1" Text='<%# Bind("field1") %>'></asp:Literal></td>
</tr>
<tr><td>><asp:Literal runat="server" ID="ltField2" Text='<%# Bind("field2") %>'></asp:Literal></td>
</tr>
</table>
</FooterTemplate>
...

You will have to create a custom GridView class by inheriting from the GridView type.
namespace CustomControls
{
public class CustomGridView : GridView
{
private string _pageTotal;
public string PageTotal
{
get { return _pageTotal; }
set { _pageTotal = value; }
}
private string _grandTotal;
public string GrandTotal
{
get { return _grandTotal; }
set { _grandTotal = value; }
}
public CustomGridView()
{
}
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Footer)
{
e.Row.SetRenderMethodDelegate(CreateFooter);
}
base.OnRowCreated(e);
}
private void CreateFooter(HtmlTextWriter PageOutput, Control FooterContainer)
{
StringBuilder footer = new StringBuilder();
footer.Append("<td>" + this._pageTotal +"</td>");
footer.Append("</tr>");
footer.Append("<tr>");
footer.Append("<td>" + this._grandTotal + "</td>");
footer.Append("</tr>");
PageOutput.Write(footer.ToString());
}
}
}
Then use the 'Register' page directive to refer to your custom control.
<%# Register TagPrefix="cc" Namespace="CustomControls" %>
Add your control to the page, make sure ShowFooter is set to true.
<cc:CustomGridView ID="GridView1" ShowFooter="true"></cc:CustomGridView>
You can then set the 'PageTotal' and 'GrandTotal' properties.
GridView1.PageTotal = "5";
GridView1.GrandTotal = "10";

Related

Dynamically added control and buttons postback

Hi I have a problem with my GridView.
Let's say that I create a GridView with 4 columns
|NAME|LASTNAME|OWNER|ADMINISTRATOR|
Owner and Administrator are columns that can contain a checkbox.
Second step: I fill the grid in some way.
Third step: I add dynamically the check box on the owner and admin columns, depending on some strange method.
Four step: When I click the Button below the gridview, the click event will read how many checkbox are checked and pass that number to another method.
This last step is quite difficult because all the checkboxes disappear, due to the postback of the button.
I looking for a method to save the checkboxes from the postback.
Can I call a method after the click, and before the postback?
Can I avoid the postback of a button?
(PS: I prefer to not go for js solution)
If you place the method call to dynamically add the check boxes in Page_Init they will not be removed on postback
It's not clear from your question why you need to have dynamically added CheckBox controls, when you can just set their state server-side in the RowDataBound event of the GridView. Here is a worked example of your requirment boiled down to the barest minimum to illustrate:
CheckboxGrid.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="CheckboxGrid.aspx.cs" Inherits="CheckboxGrid" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvResourceUsers" runat="server" AutoGenerateColumns="False" OnRowDataBound="gvResourceUsers_OnRowDataBound">
<Columns>
<asp:BoundField HeaderText="Name" DataField="Name"/>
<asp:BoundField HeaderText="Surname" DataField="Surname"/>
<asp:TemplateField HeaderText="Owner">
<ItemTemplate>
<asp:CheckBox ID="cbxOwner" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Administrator">
<ItemTemplate>
<asp:CheckBox ID="cbxAdministrator" runat="server"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button runat="server" ID="btnSubmit" Text="Save" OnClick="btnSubmit_Click"/>
</div>
</form>
</body>
</html>
CheckboxGrid.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CheckboxGrid : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Get data and bind the grid
gvResourceUsers.DataSource = GetData();
gvResourceUsers.DataBind();
}
}
protected void gvResourceUsers_OnRowDataBound(Object sender, GridViewRowEventArgs e)
{
//As each row is data-bound, set the checkbox state.
if (e.Row.RowType == DataControlRowType.DataRow)
{
var resourceUser = e.Row.DataItem as ResourceUser;
var cbxOwner = e.Row.FindControl("cbxOwner") as CheckBox;
var cbxAdministrator = e.Row.FindControl("cbxAdministrator") as CheckBox;
cbxOwner.Checked = resourceUser.Owner;
cbxAdministrator.Checked = resourceUser.Administrator;
}
}
protected void btnSubmit_Click(Object sender, EventArgs e)
{
var resourceUsers = new List<ResourceUser>();
//Iterate the gridview rows and populate the collection from the postback data.
foreach (GridViewRow row in gvResourceUsers.Rows)
{
resourceUsers.Add(
new ResourceUser
{
Name = row.Cells[0].Text,
Surname = row.Cells[1].Text,
Owner = ((CheckBox)row.Cells[2].FindControl("cbxOwner")).Checked,
Administrator = ((CheckBox)row.Cells[3].FindControl("cbxAdministrator")).Checked
});
}
}
private IEnumerable<ResourceUser> GetData()
{
//We just create some data for demo purposes. Here you would normally populate the collection from your database.
var resourceUsers = new List<ResourceUser>
{
new ResourceUser{Name = "Bob", Surname = "Taylor", Owner = true, Administrator = true },
new ResourceUser{Name = "Ann", Surname = "Carter", Owner = false, Administrator = true },
new ResourceUser{Name = "Toni", Surname = "Wong", Owner = false, Administrator = false}
};
return resourceUsers;
}
//A data view model to contain our view data for the grid
private class ResourceUser
{
public String Name { get; set; }
public String Surname { get; set; }
public Boolean Owner { get; set; }
public Boolean Administrator { get; set; }
}
}

How to hide a column in gridview accordingly to header field?

i am using a gridview to bind my datas. i want to hide a column from backend accordingly to the headerfield
<asp:TemplateField>
<HeaderTemplate>
Incident Number
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lb_incidentnumber" runat="server" Text='<%# Eval("IncidentNumber")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
i can simply write as gv_viewincident.Columns[3].Visible = false; but i want to hide the column by mentioning the headername not by giving the index..
how to do that?
This one
for (int i = 0; i < gv_viewincident.Columns.Count; i++)
{
if (gv_viewincident.Columns[i].HeaderText == "Incident Number")
{
gv_viewincident.Columns[i].Visible = false;
}
}
First, let's make an extension method to make it easier to get to the column. Put this class in your App_Code folder in a file named GridViewExtensions.cs.
public static class GridViewExtensions
{
public static DataControlField GetColumnByHeaderText(this DataControlFieldCollection dataControlFieldCollection , string headerText)
{
foreach(var column in DataControlFieldCollection)
{
if(column.HeaderText==headerText)
return column;
}
}
}
Then it's simply...
gv_viewincident.Columns.GetColumnByHeaderText("Incident Number").Visible=false;
Of course, this presumes you add header text to the column.
<asp:TemplateField HeaderText="Incident Number">
Here's one that should work:
List<DataControlField> columns = grid.Columns.Cast<DataControlField>().ToList();
columns.Find(col => col.HeaderText == "Incident Number").Visible = false;

Dynamically create different kinds of web controls

English is not my native language; please excuse typing errors.
I am creating a survey type application, and I'm not sure how I should approach so I've been doing some trials and errors.
I have a Question class
public class Question
{
public int QuestionID;
public string QuestionText;
public int InputTypeID;
public List<WebControl> Controls;
public Question()
{
//initialize fields;
}
internal Question(int id, string text, int inputTypeId)
{
//assign parameters to fields
switch(inputTypeId)
{
case 1:
//checkbox
break;
case 2:
//textbox
TextBox t = new TextBox();
Controls = new List<WebControl>();
Controls.Add(t);
break;
...
}
}
}
My Question.aspx looks like this:
<asp:Repeater ID="repeater" runat="server">
<ItemTemplate>
//Want to display a control dynamically here
</ItemTemplate>
</asp:Repeater>
I tried this but it obviously didn't work...
<asp:Repeater ID="repeater" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Controls") %>
</ItemTemplate>
</asp:Repeater>
and I just get this.
System.Collections.Generic.List`1[System.Web.UI.WebControls.WebControl] System.Collections.Generic.List`1
One question could have
one textbox
radiobutton list
checkbox list
In this case, should my Question class have List<WebControl> or just WebControl?
Also, how can I render the webcontrol inside the repeater?
You should do this in CodeBehind, using the Repeater ItemDataBound() event. Your question class should have a List<Control> which is the base class for WebControl and other controls, allowing the flexibility for different kinds of controls.
Doesn't have to use Page_Load but just for example,
void Page_Load(Object Sender, EventArgs e)
{
Repeater1.ItemDataBound += repeater1_ItemDataBound;
Repeater1.DataSource = [your List<Control> containing controls to add];
Repeater1.DataBind();
}
void Repeater1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var controlToAdd = (Control)e.Item.DataItem;
((PlaceHolder)e.Item.FindControl("PlaceHolder1")).Controls.Add(controlToAdd);
}
}
And the ItemTemplate:
<ItemTemplate>
<asp:PlaceHolder id="PlaceHolder1" Runat="server" />
</ItemTemplate>

Databind and trying to get index in Listview

Need a hand trying to get my rotating banner working properly on my website. I'm using the jquery cycle plugin which manages the rotation. Within my CMS I've got something called a smartform, which contains upto 6 pictures. The code below (something which I wrote by following a tutorial for the banner) works really well. However I would like to somehow get the index of the image and place it within the alt tags. What I am trying to achieve is the alt tag to say "Banner_(ImageIndexNumber)".
Hopefully someone can help, thanks all
C# Codebehind
private void BannerFill(int contentId)
{
try
{
uxBannerContentBlock.DefaultContentID = contentId;
uxBannerContentBlock.Fill();
string xml = uxBannerContentBlock.EkItem.Html;
SmartForm.RotatingBanner.BannerImage bannerGroup = (SmartForm.RotatingBanner.BannerImage)
Ektron.Cms.EkXml.Deserialize(typeof(SmartForm.RotatingBanner.BannerImage), xml);
List<BannerSlide> slides = GetBannerSlides(bannerGroup.Slides);
//Databind//
uxBannerRepeater.DataSource = slides;
uxBannerRepeater.DataBind();
}
catch { }
}
protected List<BannerSlide>
GetBannerSlides(SmartForm.RotatingBanner.BannerImageSlides[] bannerGroupSlides)
{
List<BannerSlide> bSlides = new List<BannerSlide>();
foreach (SmartForm.RotatingBanner.BannerImageSlides bgSlide in bannerGroupSlides)
{
bSlides.Add(new BannerSlide(bgSlide.Image.img.src));
}
return bSlides;
}
public class BannerSlide
{
//properties//
public string SlideImage { get; set; }
//constructor//
public BannerSlide(string slideImage)
{
SlideImage = slideImage;
}
}
Front end
<div class="slideshow">
<CMS:ContentBlock ID="uxBannerContentBlock" runat="server" Visible="false" />
<asp:Repeater runat="server" ID="uxBannerRepeater">
<ItemTemplate>
<img src="<%# DataBinder.Eval( Container.DataItem,"SlideImage") %>" alt="Banner_<%# Container.ItemIndex %>" />
</ItemTemplate>
</asp:Repeater>
alt='<%# "Banner_" + Container.ItemIndex %>'

ASPxGridView, ITemplate, and Eval

How can I create a template in c# for an AXPxGridViewDataTextColumn without any markup and with using Eval to display the DataItem value?
-The problem that I am having is that the string "<%#Eval("dataTableField1")%>" shows up in the GridView for every row instead of the appropriate values.
Here is an example of my attempt:
public override void DataBind()
{
...
GridViewDataTextColumn myCol = new GridViewDataTextColumn();
myCol.Caption = "col1";
myCol.FieldName = "dataTableField1";
myCol.DataItemTemplate = new ColumnDataItemTemplate();
theGridView.Columns.Clear();
theGridView.Columns.Add(myCol);
theGridView.DataSource = AdjustDataSource();
theGridView.DataBind();
...
}
public class ColumnDataItemTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
GridViewDataItemTemplateContainer Container = (container as GridViewDataItemTemplateContainer);
LiteralControl lit = new LiteralControl("<div id=\"hr\" style=\"height:100%\"><%#Eval(\"dataTableField1\")%></div>");
Container.Controls.Add(lit);
}
}
Here is an example of what I want to do with the row height taken from this link:
<dx:GridViewDataTextColumn FieldName="Description" VisibleIndex="3">
<DataItemTemplate>
<div id="hr" style="height:100%">
<%#Eval("Description")%>
</div>
</DataItemTemplate>
</dx:GridViewDataTextColumn>
This documentation link shows similar examples of using templates in the markup but I want to do it in the code behind.
Here is a link on creating templates.
Thanks in advance,
Soenhay
Edit:
I was able to get the first element to properly display by moving the template assignment to the CustomColumnDisplayText event but all other elements displayed in the ASPxGridView show the Eval string.
I had 2 other solutions but I removed them as I think this is the best ( I would be grateful for any other suggestions/improvements ):
public override void DataBind()
{
...
GridViewDataTextColumn myCol = new GridViewDataTextColumn();
myCol.Caption = "col1";
myCol.FieldName = "dataTableField1";
myCol.DataItemTemplate = new ColumnDataItemTemplate();
theGridView.Columns.Clear();
theGridView.Columns.Add(myCol);
theGridView.DataSource = AdjustDataSource();
theGridView.DataBind();
...
}
public class ColumnDataItemTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
GridViewDataItemTemplateContainer Container = (container as GridViewDataItemTemplateContainer);
LiteralControl lit = new LiteralControl("<div id='hr' style='height:100%; font-size:x-large;'>" + DataBinder.Eval(Container.DataItem, Container.Column.FieldName) + "</div>");
Container.Controls.Add(lit);
}
}
At this link I have found a reason to not use the event:
"The CustomColumnDisplayText event should not be handled for template columns. "
This link helped with the DataBinder.Eval part.
Heres an example but mine is binding with a database, i usually use EditTemplte
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="BSA" SortExpression="BSA">
<ItemTemplate>
<asp:Label ID="lblBSA" runat="server" Text='<%# Bind("BSA") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>

Categories