how to add a rowspan to the first column in a gridview? - asp.net

I have a gridview and in the first column I added a table to create a second row:
I would like the shipper address to span across all the columns in the gridview.
Code:
<asp:GridView CssClass="printTableResults" runat="server" ID="gvHawb"
ShowHeaderWhenEmpty="false"
DataKeyField="ID"
OnRowDataBound="gvHawb_RowDataBound"
AutoGenerateColumns="false"
allowpaging="false">
<HeaderStyle CssClass="printTableHeader" />
<RowStyle CssClass="borderB" />
<Columns>
<asp:TemplateField HeaderText="HAWB" HeaderStyle-Font-Bold="true" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<table>
<tr>
<td><asp:Label ID="lblAwbNumber" runat="server" Text='<%# Eval("AWBNumber") %>'></asp:Label></td>
</tr>
<tr>
<td><label>Shipper</label></td>
<td><asp:Label ID="lblFullShipperAddress" runat="server" Text='<%# Eval("FullShipperAddress") %>'></asp:Label></td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Pieces" HeaderStyle-Font-Bold="true" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Label ID="lblPieces" runat="server" Text='<%# Eval("TotalNoOfPieces") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Is there a way to make shipper span the rows of the gridview?
There is a total of 8 columns in this gridview.

You could try moving the table with the shipper address to the ItemTemplate of the last column in the outer table. Then put the table on its own tr. Something like this:
<ItemTemplate>
<asp:Label ID="lblPieces" runat="server" Text='<%# Eval("TotalNoOfPieces") %>'></asp:Label>
</tr> <!-- end the outer table row -->
<tr colspan="7"> <!-- start new row in the outer table -->
<table>
<tr>
<td><asp:Label ID="lblAwbNumber" runat="server" Text='<%# Eval("AWBNumber") %>'></asp:Label></td>
</tr>
<tr>
<td><label>Shipper</label></td>
<td><asp:Label ID="lblFullShipperAddress" runat="server" Text='<%# Eval("FullShipperAddress")%>'></asp:Label></td>
</tr>
</table>
</ItemTemplate>
Note that you should not finish up with an ending </tr> because the outer table rendering will add that.
This answer was put together without any real testing so I'm not guaranteeing that it will work "out of the box".

If you want the first cell to span all 8 columns of the row, you can add this handler to the PreRender event of the GridView:
void gvHawb_PreRender(object sender, EventArgs e)
{
foreach (GridViewRow row in gvHawb.Rows)
{
if (/* some condition */)
{
// Remove the other cells of the row
while (row.Cells.Count > 1)
{
row.Cells.RemoveAt(1);
}
// Set the ColumnSpan attribute
row.Cells[0].ColumnSpan = 8;
}
}
}
I assume that it would be done on rows that meet a specific condition.
You may also consider using a ListView, which is easier to customize than the GridView.

Related

How to Add a blank row to asp repeater during ItemDataBound event?

I bind the repeater with SqlDataReader but I want when repater has no row than a blank row is added in ItedDataBound Event
1- First Create A DataTable Object to hold your data
2- Check for the Number of Rows in the DataTable if Zero then Add Empty DataRow Object To DataTable
3- Bind Your Repeater to the DataTable Instead to Datareader Object
if(dt.Rows.Count==0)
{
DataRow dr=dt.NewRow();
dt.Rows.Add(dr);
}
rptDemo.DataSource=dt;
rptDemo.DataBind();
Try this.
Place label in the footer of repeater in FooterTemplate and by default set visible to false and in ItemDataBound set to visible=true when item count is 0 or less than 1.
<asp:Repeater ID="rptDemo" runat="server"
OnItemDataBound="rptDemo_ItemDataBound">
<ItemTemplate>
.......
</ItemTemplate>
<FooterTemplate>
<%-- Label used for no data available --%>
<asp:Label ID="lblMsg" runat="server" CssClass="errMsg" Text="Sorry, no item is there to show." Visible="false">
</asp:Label>
</FooterTemplate>
protected void rptDemo_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (rptDemo.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
Label lblFooter = (Label)e.Item.FindControl("lblMsg");
lblFooter.Visible = true;
}
}
}
Hope this helps!
My requirement was to show add row inside repeater. Me included a blank row as the last item by doing a small checking, in all other rows, blank row made hidden.
Used
<%# (((IList)((Repeater)Container.Parent).DataSource).Count).ToString() == (Container.ItemIndex + 1).ToString() %>
checking to decide whether to show or hide blank row.
Full code of view:
<table>
<asp:Repeater ID="repeater1" OnItemCommand="repeater_user_Itemcommand" runat="server">
<HeaderTemplate>
<tr>
<td>
Name
</td>
<td>
Email
</td>
<td>
Delete
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Label ID="lblName" runat="server" Text='<%# DataBinder.Eval(Container.DataItem,"Name") %>'></asp:Label>
</td>
<td>
<asp:Label ID="lblEmail" runat="server" Text='<%# Eval("Email") %>'></asp:Label>
</td>
<td>
<asp:LinkButton ID="btnDelete" runat="server" CommandArgument='<%# Eval("ID") %>'
CommandName="delete">Delete</asp:LinkButton>
</td>
</tr>
<tr id="Tr1" runat="server" visible='<%# (((IList)((Repeater)Container.Parent).DataSource).Count).ToString() == (Container.ItemIndex + 1).ToString() %>'>
<td>
<asp:TextBox ID="txtName_add" runat="server" Enabled="True" Text='' Visible="false"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="txtEmail_add" runat="server" Text='' Visible="false"></asp:TextBox>
</td>
<td>
<asp:LinkButton ID="btnShowAdd" runat="server" CommandName="add">Add</asp:LinkButton>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>

SortExpression in ASP.NET GridView not working with <HeaderTemplate>

I have an ASP.NET GridView. Now I am adding the SortExpression property tothe <TemplateField> tags, to make specific columns sortable.
Now, one of the columns has some markup content to be added in the header. The problem is, SortExpression does not work if there is a <HeaderTemplate> tag in a <TemplateField>, you have to put it inside the HeaderText property of <TemplateField>. But, all the HTML content does not work properly if I dump it inside the HeaderText property.
<asp:TemplateField SortExpression="FK_TesterID" ItemStyle-Width="300px" FooterStyle-Width="300px" ItemStyle-HorizontalAlign="Center" FooterStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center">
<HeaderTemplate>
<table width="100%">
<tr>
<td align="center">
Tester
</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="cmbTestersHeader" ClientIDMode="Static" runat="server" Width="300px" DataSource='<%# PopulateTesterNames() %>' DataTextField="FullName" DataValueField = "PK_ID" Visible="false" AutoPostBack="true" OnSelectedIndexChanged="cmbTestersHeader_SelectedIndexChanged" ToolTip="Bulk Assign Testers !" ></asp:DropDownList>
</td>
</tr>
</table>
</HeaderTemplate>
So you can see, if I put the entire <HeaderTemplate> property inside a headertext, it doesn't work.
But I want to have both functionalities. Can anyone help?
Then you need to provide a control in your HeaderTemplate with CommandName="Sort", for example a LinkButton.
<HeaderTemplate>
<table width="100%">
<tr>
<td align="center">
<asp:LinkButton ID="LbSort" runat="server" CommandName="Sort" Text="Sort" />
</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="cmbTestersHeader" ClientIDMode="Static" runat="server" Width="300px"
DataSource='<%# PopulateTesterNames() %>' DataTextField="FullName" DataValueField="PK_ID"
Visible="false" AutoPostBack="true" OnSelectedIndexChanged="cmbTestersHeader_SelectedIndexChanged"
ToolTip="Bulk Assign Testers !">
</asp:DropDownList>
</td>
</tr>
</table>
</HeaderTemplate>
This is a quite old thread I have stumbled over while trying to solve exactly that described problem but the solution provided here didn't worked for me. If you have a Sorting method defined for the GridView then
<asp:LinkButton ID="LbSort" runat="server" CommandName="Sort" Text="Sort" />
will call that method
protected void GridView_Sorting(object sender, GridViewSortEventArgs e)
{
dt.DefaultView.Sort = e.SortExpression;
but e.SortExpression will be null and no sorting is happening. You have to first pass the Column's name through the CommandArgument of the LinkButton. Only then it worked in my case!
<asp:LinkButton ID="LbSort" runat="server" CommandName="Sort" CommandArgument="ColumnName" Text="Sort" />

First row of DataGrid not being filled in with DataList data

I have a DataGrid with 4 columns and a DataList with 5 columns. The DataList resides inside the DataGrid as another separate column by itself.
Everything is coming out fine, except that the first row in the datagrid does not display the contents of the datalist. It's as if everything in my datalist should be pushed up by a 1 row to display the data correctly.
I have validated (during debugging) that the data is coming out fine in the datalist for the corresponding first row of the datagrid, but it doesn't get rendered on the first row of the datagrid. It starts to get rendered on the second row of the datagrid.
I've been over this numerous times with the markup and the codebehind, and can't figure out why this is happening. Any help would be appreciated.
Below is my code:
HTML
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="referrals.ascx.cs" Inherits="dpbrokers.dpbrokers.referrals"
TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<div align="center">
<asp:Label ID="errormessage" runat="server" Visible="False" /></div>
<asp:DataGrid ID="lstReferrals" runat="server" DataKeyField="ReferringAffiliateID"
AutoGenerateColumns="false" CellPadding="4" OnItemDataBound="lstReferrals_ItemDataBound">
<AlternatingItemStyle Font-Size="9pt" CssClass="small" BackColor="#C2D6FA"></AlternatingItemStyle>
<ItemStyle Font-Size="9pt" CssClass="small" BackColor="White"></ItemStyle>
<HeaderStyle Font-Size="11pt" Font-Bold="True" ForeColor="White" BackColor="#ABACAD">
</HeaderStyle>
<Columns>
<asp:TemplateColumn HeaderText="Referring Affiliate">
<ItemTemplate>
<asp:HyperLink Text='<%# DataBinder.Eval(Container.DataItem, "ReferringAffiliateName") %>'
NavigateUrl='<%# EditURL("Referral",DataBinder.Eval(Container.DataItem, "ReferralID").ToString(),"Edit",0) %>'
runat="server" ID="Hyperlink1" />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="SkyCard Awarded">
<ItemTemplate>
<asp:Label ID="itemAward" runat="server" Text='<%# IsAwarded(DataBinder.Eval(Container.DataItem, "IsAwarded").ToString()) %>' />
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="DSMAffiliateName" HeaderText="District Sales Manager">
</asp:BoundColumn>
<asp:BoundColumn DataField="DSMAffiliatePhone" HeaderText="DSM Phone"></asp:BoundColumn>
<asp:TemplateColumn>
<ItemTemplate>
<asp:DataList ID="DetailList" ItemStyle-CssClass="small" DataSource="<%# riReferrals %>"
runat="server" Width="100%">
<HeaderTemplate>
<table width="100%" cellpadding="4" border="1">
<tr bgcolor="#ABACAD" class="normalwhite">
<td width="25%">
Referral Name
</td>
<td width="20%">
Phone Number
</td>
<td width="30%">
Email
</td>
<td>
Referred On
</td>
<td>
Is Member?
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr class="small">
<td>
<asp:HyperLink Text='<%# DataBinder.Eval(Container.DataItem, "ContactName") %>' NavigateUrl='<%# EditURL("ReferralID",DataBinder.Eval(Container.DataItem, "ReferralID").ToString(),"Edit",0) %>'
runat="server" ID="Hyperlink2" />
</td>
<td>
<%# FormatPhone(DataBinder.Eval(Container.DataItem,"Phone").ToString()) %>
</td>
<td>
<%# FormatForEmail(DataBinder.Eval(Container.DataItem, "Email").ToString())%>
</td>
<td>
(<%# DataBinder.Eval(Container.DataItem,"Created", "{0:g}") %>)
</td>
<td>
(<%# IsMember(DataBinder.Eval(Container.DataItem, "JoinedON").ToString())%>)
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
<div align="right">
<asp:ImageButton ID="Button1" CommandName="award" ImageUrl="~/images/dpbbuttons/awardbutton.gif"
AlternateText="Award SkyCard" runat="server" /></div>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
<PagerStyle Mode="NumericPages"></PagerStyle>
</asp:DataGrid>
CODE BEHIND
public ArrayList riReferrals;
protected void Page_Load(System.Object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
LoadReferrals();
}
private void LoadReferrals()
{
try
{
ReferralController objReferral = new ReferralController();
lstReferrals.DataSource = objReferral.GetReferrals();
lstReferrals.DataBind();
}
catch (Exception ex)
{
Response.Write(ex);
CLogError clsLogError = new CLogError(ex, Request, Session, Context.User.Identity.Name);
clsLogError.LogError();
}
}
public void lstReferrals_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
switch (e.Item.ItemType)
{
case ListItemType.Item:
case ListItemType.AlternatingItem:
lbl1 = (Label)e.Item.FindControl("itemAward");
GetDtlReferrals(Convert.ToInt32(lstReferrals.DataKeys[e.Item.ItemIndex]));
button.Visible = true;
if (lbl1.Text.ToLower() == "No")
button.Attributes.Add("onClick", "javascript:return confirm(\'Are You Sure You Wish To Award a SkyCard to this Agent ?\');");
else
{
button.ImageUrl = "~/images/dpbbuttons/revokebutton.gif";
button.Attributes.Add("onClick", "javascript:return confirm(\'Are You Sure You Wish To Revoke the SkyCard Award for this Agent ?\');");
}
break;
}
}
public ArrayList GetDtlReferrals(Int32 KeyField)
{
riReferrals = null;
try
{
// Obtain a list of discussion messages for the module
ReferralController objReferral = new ReferralController();
riReferrals = objReferral.GetReferralsByAgentID(KeyField);
}
catch (Exception ex)
{
Response.Write(ex);
CLogError clsLogError = new CLogError(ex, Request, Session, Context.User.Identity.Name);
clsLogError.LogError();
}
return riReferrals;
}
Got it!
In the GetDtlsReferrals method, I added the following code snippet which produced the display data I was looking for:
DataList DetailList = (DataList)e.Item.FindControl("DetailList");
DetailList.DataBind();

ASP.NET + GridView + EmptyDataTemplate

I have an ASP.NET GridView that uses an EmptyDataTemplate. This template is used to collect data in the event that no records exist in my data source. My GridView source looks like this:
<asp:GridView ID="myGridView" runat="server"
DataKeyNames="ID" OnRowEditing="myGridView_RowEditing"
OnRowCancelingEdit="myGridView_RowCancelingEdit"
OnRowUpdating="myGridView_RowUpdating"
ShowFooter="True" EnableModelValidation="True">
<Columns>
<asp:BoundField DataField="ID" Visible="false" />
<asp:TemplateField HeaderText="Name">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Name") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Name") %>'></asp:Label>
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="nameFooterTextBox" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Age">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("Age") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("Age") %>' />
</ItemTemplate>
<FooterTemplate>
<asp:TextBox ID="ageTextBox" runat="server" />
</FooterTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Options" HeaderStyle-HorizontalAlign="Left"
ButtonType="Link" ShowEditButton="true" ShowDeleteButton="true" >
</asp:CommandField>
</Columns>
<EmptyDataTemplate>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>Name</td>
<td>Age</td>
<td>Options</td>
</tr>
<tr>
<td><asp:TextBox ID="nameTextBox" runat="server" /></td>
<td><asp:TextBox ID="ageTextBox" runat="server" /></td>
<td><asp:LinkButton ID="saveLinkButton" runat="server" Text="save" OnClick="saveLinkButton_Click" /></td>
</tr>
</table>
</EmptyDataTemplate>
When a user clicks the "saveLinkButton" in the EmptyDataTemplate, I want to get the values from the TextBoxes and insert a new record into my data source. My question is, how do I get the values of those text fields when somebody clicks the "saveLinkButton"?
Thank you!
This thread over at asp.net proposes a solution to this problem (Note: I haven't tried it out)
http://forums.asp.net/p/1436652/3240106.aspx
You need to handle the RowCommand event, get the parent naming container of the control that raise the event (your linkbutton) and then search for the textboxes using FindControl within that.
Try this to get the values of the name and age in row command of the grid..
Before doing this set the command name of the saveLinkbutton to MyInsert and remove the onlcik event as u may not need it.
protected void yourGridview_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("MyInsert"))
{
TextBox nameTextBox= gvEligibility.Controls[0].Controls[0].FindControl("nameTextBox") as TextBox;
TextBox ageTextBox= gvEligibility.Controls[0].Controls[0].FindControl("ageTextBox") as TextBox;
string name=nameTextBox.Text();
string age=ageTextBox.Text();
//save code here
}
}

Master/Detail help needed for ASP.NET newbie. (screenshot too)

I'm just beinning basic data driven ASP.NET webforms design. I have the first part of a form working, but I don't know what to do next.
Please see this screenshot of what I have created so far: http://www.twitpic.com/2gnmr
I need help knowing what kind of HTML element to use in the master list, and what event/trigger on that element to use to fire off the "get child records for this selected item" sequence?
Also, is a ListView even the correct way to present the master list? At this time, I'm not trying to provide any editing features; I'll get to that later, I guess.
Should I use some other ASP.NET data control rather than hand-coding a listview like I am doing?
I don't want to see an actual "Select" link item beside each Customer Name (that looks goofy). I want the Customer Name to be the link to click on.
So, you can see in my code below that I have a ListView to present a list of CustomersWithOpenOrders. But, it's just a static list, so how do I make the Company Name label clickable, and what else will I need to make it fire back to some code-behind to fetch the child records. I already have a code-behind method to get child records for a passed-in CustomerNumber into a DataTable, and I think I would know how to bind that to a grid or listview for child records, but I do not know how to pass the CustomerNumber from the master ListView to the method from the UI form.
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<table cellpadding="2" border="0" ID="tbl1" runat="server">
<tr id="Tr1" runat="server" class="lvHeader">
<th id="Th1" runat="server">Customer</th>
</tr>
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr id="Tr2" runat="server">
<td>
<asp:Label ID="label2" class="FirstLine" runat="server" Text='<%# Eval("company") %>' />
<br />
<div class="SecondLine">
<asp:Label ID="labelCustNo" runat="server" Text='<%# Eval("custno") %>'/>
<asp:Label runat="server" Text='Ph: '></asp:Label>
<asp:Label ID="label3" runat="server" Text='<% # Eval("phone") %>' />
</div>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
I personally haven't found a case where the ListView can't solve my needs. If you want to create a customer selection style list you can use a link button for binding.
<asp:ListView runat="server" id="CustomersList" ItemCommand="CustomersList_ItemCommand">
<LayoutTemplate>
<table cellpadding="2" border="0" ID="tbl1" runat="server">
<tr id="Tr1" runat="server" class="lvHeader">
<th id="Th1" runat="server">Customer</th>
</tr>
<tr runat="server" id="itemPlaceholder" />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr id="Tr2" runat="server">
<td>
<asp:LinkButton ID="link1" class="FirstLine" runat="server" Text='<%# Eval("company") %>' CommandName="Select" />
<br />
<div class="SecondLine">
<asp:Label ID="labelCustNo" runat="server" Text='<%# Eval("custno") %>'/>
<asp:Label runat="server" Text='Ph: '></asp:Label>
<asp:Label ID="label3" runat="server" Text='<% # Eval("phone") %>' />
</div>
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:ListView runat="server" ID="OrderList">
<!-- Child Rows implementation -->
</asp:ListView>
Then you would need to bind the event to the ListView.ItemCommand.
protected void CustomersList_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName = "Select")
{
if (e.Item.ItemType != ListViewItemType.DataItem) return;
var dataItem = e.Item as ListViewDataItem;
if (dataItem == null) return;
var customer = dataItem.DataItem as Customer;
if (customer == null) return;
this.OrdersList.DataSource = GetChildRecords(customer.ID);
this.OrdersList.DataBind();
}
}

Resources