Asp.Net ListView's Items property is always empty - asp.net

Good day
I have a user control that contains a ListView which is being used to display tabs.
I am databinding the ListView and on the OnItemDataBound event adding the tab elements.
However the Items property never contains anything and is always empty (on PostBack and on ItemDataBound).
Markup:
<asp:ListView ID="SaleTabsListView" runat="server" OnItemDataBound="SaleTabsListView_OnItemDataBound" ItemPlaceholderID="SaleTabsPlaceHolder" EnableViewState="true">
<LayoutTemplate>
<div class="tabs">
<asp:PlaceHolder runat="server" ID="SaleTabsPlaceHolder" />
</div>
</LayoutTemplate>
<ItemTemplate>
<asp:PlaceHolder runat="server" ID="ItemPlaceHolder" />
</ItemTemplate>
</asp:ListView>
Code behind:
protected void SaleTabsListView_OnItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var saleTab = ((ListViewDataItem)e.Item).DataItem as SalesTab;
if (saleTab != null)
{
var placeHolder = e.Item.FindControl("ItemPlaceHolder") as PlaceHolder;
var htmlAnchor = new HtmlAnchor();
htmlAnchor.Attributes.Add("id", saleTab.Id);
htmlAnchor.Attributes.Add("class", saleTab.IsCurrent ? currentTabClass : string.Empty);
var emptyLabel = new Label();
var label = new Label {Text = saleTab.Title};
label.Attributes.Add("id", saleTab.Id + "Label");
label.Attributes.Add("class", saleTab.IsComplete ? completeClass : incompleteClass);
emptyLabel.Controls.Add(label);
htmlAnchor.Controls.Add(emptyLabel);
placeHolder.Controls.Add(htmlAnchor);
}
}
}
So my question is: is the binding I'm doing somehow screwing with the Items property?
Thanks

Related

How do I display child footer of a repeater if the child repeater is empty?

I have two repeaters nested in my application which is working fine. I would love to display the footer if the child repeater is empty. Due to my code my long html, i will just drop a sample of what my html looks like and post my full code for better understanding. Everything works fine though unless when the child repeater is empty i want to display the footer message
<asp:Repeater ID="ProductRepeater" runat="server" OnItemDataBound="ProductRepeater_ItemDataBound">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<table>
<tr>
<td>
<%#Eval("Name")%>
</td>
<tr>
</table>
<pre>
<asp:Repeater ID="ChildRepeater" runat="server">
<HeaderTemplate></HeaderTemplate>
<ItemTemplate>
<table>
<tr>
<td>
<%#Eval("Description")%>
<td>
</tr>
<table>
</itemTemplate>
<FooterTemplate>
<div>
<h5>
<asp:Label ID="lblDefaultMessage" runat="server" Text="This is empty. " Visible="false" ForeColor="Red" Font-Size="Large">
</asp:Label>
</h5>
</div>
</FooterTemplate>
</asp:Repeater>
</pre>
</ItemTemplate>
</asp:Repeater>
<protected void ProductRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
string category = "Value"
Repeater rptRelated = e.Item.FindControl("ChildRepeater") as Repeater;
rptRelated.DataSource = getChild(category);
rptRelated.DataBind();
if (rptRelated.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
Label lblDefaultMessage = (Label)e.Item.FindControl("lblDefaultMessage");
lblDefaultMessage.Visible = true;
}
}
}
}
Repeater has no EmptyDataTemplate like GridView.
You should place your footer content next to Repeater and change your "databinding" code like this:
Repeater rptRelated = e.Item.FindControl("ChildRepeater") as Repeater;
Label lblDefaultMessage = (Label)e.Item.FindControl("lblDefaultMessage");
var ds = getChild(category);
lblDefaultMessage.Visible = ds != null && ds.Rows.Count != 0;
if (rptRelated != null)
{
rptRelated.DataSource = ds;
rptRelated.DataBind();
}
Find Repeater like:
// find Child Repeater
Control ctrl = (sender) as Control;
Repeater rptRelated = ctrl.Parent.NamingContainer as Repeater;
And Find control from Repeater's Footer like:
Label lblDefaultMessage =
(Label)rptRelated.Controls[rptRelated.Controls.Count-1].FindControl("lblDefaultMessage");
Add this into child Repeater's OnItemDataBound event instead of parent.
protected void ChildRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Control ctrl = (sender) as Control;
Repeater rptRelated = ctrl.Parent.NamingContainer as Repeater;
if (rptRelated.Items.Count < 1)
{
if (e.Item.ItemType == ListItemType.Footer)
{
Label lblDefaultMessage = (Label)rptRelated.Controls[rptRelated.Controls.Count-1].FindControl("lblDefaultMessage");
lblDefaultMessage.Visible = true;
}
}
}
Event is:
<asp:Repeater ID="ChildRepeater" runat="server"
OnItemDataBound="ChildRepeater_ItemDataBound">

Nested ListView DataPager stops working with updatepanel

Here is my scenario:
I have several deals, each has a category, all are grouped by categories as such:
DealView: Name (the category), Deals (List of Deals objects)
the DealViews (List) is bound to the category list view, the listview on item databound generates the corresponding inner listviews and sets their corresponding data pagers paging size,it also decides whether to show the inner pagers or not. The OnLoad event of the categories listview is used for the postback of the any of the internal pagers. I can debug the code and i can see that the Load event is executed, the inner pagers SetPageProperties are also set correctly however nothing changes on the UI no matter how many times I click. If I remove the updatepanel, everything works as expected. Here is some, or alot of code :)
<div class="tabs-content">
<asp:UpdatePanel ID="upDeals" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:ListView ID="lvCategorisedDeals" runat="server" DataKeyNames="Deals" >
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
<div class="clear"></div>
</LayoutTemplate>
<ItemTemplate>
<div class="tab-item">
<asp:ListView runat="server" ID="lvCategoryDeals">
<LayoutTemplate>
<div class="deals">
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</div>
<div class="clear"></div>
</LayoutTemplate>
<ItemTemplate>
<div class="rc-item">
<h3><%# Eval("Title") %></h3>
<div class="deal-img">
<img src="<%# Eval("ImageUrl") %>" width="168" height="113">
</div>
<div class="deal-data">
<div class="info"><%# Eval("Caption") %></div>
<div class="price"><%# Eval("Currency") %> <%# Eval("DiscountedPrice") %></div>
<div class="deal-booking">Buy Now</div>
</div>
</div>
</ItemTemplate>
</asp:ListView>
<div class="dealsPager">
<asp:DataPager runat="server" ID="pgInner" PagedControlID="lvCategoryDeals" >
<Fields>
<asp:NumericPagerField />
</Fields>
</asp:DataPager>
</div>
</div>
</ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
And in the code behind:
void lvCategorisedDeals_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
foreach (var item in lvCategorisedDeals.Items)
{
if (item.ItemType == ListViewItemType.DataItem)
{
var lvInner = item.FindControl("lvCategoryDeals") as ListView;
if (lvInner == null)
throw new InvalidOperationException("The inner ListView was not found");
var pgInner = item.FindControl("pgInner") as DataPager;
if (pgInner == null)
throw new InvalidOperationException("The inner pager was not found");
if (lvCategorisedDeals.DataKeys == null && lvCategorisedDeals.DataKeys.Count == 0)
throw new InvalidOperationException("The outer ListViews Datakeys do not seem to be set");
var dataItem = lvCategorisedDeals.DataKeys[item.DisplayIndex].Value as List<GRCDeal>;
lvInner.PagePropertiesChanging += new EventHandler<PagePropertiesChangingEventArgs>(
(s, evt) =>
{
pgInner.SetPageProperties(evt.StartRowIndex, evt.MaximumRows, false);
// Get the data for the ListView lvInner
lvInner.DataSource = dataItem;
lvInner.DataBind();
}
);
}
}
}
}
void lvCategorisedDeals_ItemDataBound(object sender, ListViewItemEventArgs e)
{
var listViewDataItem = e.Item as ListViewDataItem;
if (listViewDataItem == null)
return;
if (listViewDataItem.ItemType == ListViewItemType.DataItem)
{
var lvInner = e.Item.FindControl("lvCategoryDeals") as ListView;
if (lvInner == null)
throw new InvalidOperationException("The inner ListView was not found");
var pgInner = e.Item.FindControl("pgInner") as DataPager;
if (pgInner == null)
throw new InvalidOperationException("The inner pager was not found");
var dataItem = listViewDataItem.DataItem as DealView;
pgInner.PageSize = this.PageSize;
pgInner.Visible = dataItem.Deals.Count > this.PageSize;
lvInner.DataSource = dataItem.Deals;
lvInner.DataBind();
}
Additional things to note is that I am passing that List of Deals as DataKeys and I am able to grab it fine. First binding happens on page load. The code is inside a user control part of Visual WebPart (SharePoint 2013).
Appreciate any help since this is killing me.

Repeater inside repeater not binding properly

I have a repeater inside another. Like so :
<asp:Repeater ID="CategoryRepeater" runat="server" OnItemDataBound="ItemBound">
<ItemTemplate>
<div class="groupbox">
<fieldset>
<legend><%# Container.DataItem %></legend>
<table>
<asp:Repeater ID="ItemRepeater" runat="server">
<ItemTemplate>
<tr>
<td>
<asp:CheckBox id="chkItem" runat="server" Text='<%# Eval("Text")%>' />
<asp:Button ID="btnXRefs" Text="x-refs" runat="server" CssClass="xRefButton" OnClick="btnSelectXRefs_Click" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
</fieldset>
</div>
</ItemTemplate>
</asp:Repeater>
CODE BEHIND :
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
using (var db = new DbContext())
{
CategoryRepeater.DataSource = db.Categories.OrderBy(x => x.Heading).Select(x => x.Heading).Distinct();
CategoryRepeater.DataBind();
}
}
}
protected void ItemBound(object sender, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.Item)
{
Repeater childRepeater = (Repeater)args.Item.FindControl("ItemRepeater");
var item = args.Item as RepeaterItem;
using (var db = new DbContext())
{
childRepeater.DataSource = db.Categories.Where(x => x.Heading == item.DataItem).OrderBy(x => x.Text);
childRepeater.DataBind();
}
}
}
My goal is to first make many groupboxes using the top level, then bind items into each one. So I end up with many small stacked lists of checkboxes.
Problem is, all the top level boxes appear, yet only the first one contains checkbox items, ie. only the first one is bound internally, and the ItemBound method is only called once for the first one.
Any ideas why?
This line
if (args.Item.ItemType == ListItemType.Item)
Should be like this
if(args.Item.ItemType = ListItemType.Item ||
args.Item.ItemType == ListItemType.AlternatingItem)

How bind Checklistbox inside repeater control having datasource as LINQ

i my website i am using Repeater control which further contain checkboxlist control.
Now my problem is that i have successfully bind "Parameter Type" in repeater control but when i am binding checkbox values, it does't appears in display
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<h4>
<%#Container.DataItem%></h4>
<asp:CheckBoxList ID="chkParList" runat="server" RepeatDirection="Horizontal"
DataTextField = >
</asp:CheckBoxList>
<br /><br />
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater>
In *.cs file following are my code
IMonitoringDataInfo objMonitoringDataInfo = new ChannelFactory<IMonitoringDataInfo>("MonitoringDataInfo").CreateChannel();
Collection<ParameterDetailDTO> clParameterDetailDTO = objMonitoringDataInfo.GetAllParameters(idList, out errorCode);
var parameters = (from resx in clParameterDetailDTO
select resx.ParameterType).Distinct();
Repeater1.DataSource = parameters.ToList();
Repeater1.DataBind();
counter = Repeater1.Items.Count;
while (i < counter - 1)
{
foreach (var parType in parameters)
{
var items = from resx in clParameterDetailDTO
where resx.ParameterType.ToLower().Contains(parType.ToLower())
select new { resx.ParameterName, resx.ParameterID };
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataSource = items;
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataTextField = "ParameterName";
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataValueField = "ParameterID";
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataBind();
}
i++;
}
I am using LINQ as datasource
Please help?
add OnItemDataBound event to Repeater :
<asp:Repeater ID="Repeater1" OnItemDataBound="Repeater1_ItemDataBound" runat="server">
then in code behind do something like this :
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var parameters = (from resx in clParameterDetailDTO
select resx.ParameterType).Distinct();
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
CheckBoxList chkParList = (e.Item.FindControl("chkParList") as CheckBoxList);
chkParList.DataSource = parameters.ToList();
chkParList.DataTextField = "ParameterName";
chkParList.DataValueField = "ParameterID";
chkParList.DataBind();
}
}
Try putting your CheckBoxList binding inside the ItemDataBound event of the repeater.
See:
Repeater.ItemDataBound Event
Using OnItemDataBound with Repeater in ASP.NET and C#

Working with Datalist in asp.net?

good morning to all.
i place a datalist in my project in that i place a link button when i click on that link button a panel will open in that row with a textbox and a button. it is working fine but my problem is if i click on one link button of a row panel will open, when i click on second row link button the sencond row panel is opening but first row panel is not closing. I think you get my point owhter wise i will explain again this is my code check out
<form id="form1" runat="server">
<div>
<asp:DataList ID="Mydatalist" runat ="Server"
OnItemCommand="Mydatalist_ItemCommand" >
<ItemTemplate >
<table >
<tr>
<td>
<asp:Label ID="lblcouname" runat ="server"
Text ='<%# Eval("country_name") %>'></asp:Label>
</td>
<td>
<asp:LinkButton ID="lnkrepl" Text="reply"
CommandName ="reply" runat ="server"
CommandArgument ='<%# Eval("country_id") %>'>
</asp:LinkButton>
</td>
</tr>
</table>
<div>
<asp:Panel ID="mypane" runat ="Server" Visible ="false" >
<asp:TextBox ID="txtpane" runat ="Server" ></asp:TextBox><br />
<asp:Button ID="btnInsert" runat="Server" Text ="Insert" />
</asp:Panel>
</div>
</ItemTemplate>
</asp:DataList>
</div>
</form>
Code behind:
public partial class Datlist : System.Web.UI.Page
{
SqlConnection con; SqlDataAdapter da; DataSet ds;
protected void Page_Load(object sender, EventArgs e)
{
con = new SqlConnection(
#"server=msmsm;database=pop;user id=sa;password=abc");
con.Open();
if (!IsPostBack)
{
getCountry();
}
}
public void getCountry()
{
string sqr="select * from country";
da=new SqlDataAdapter (sqr,con);
ds = new DataSet();
da.Fill(ds,"country");
Mydatalist.DataSource = ds.Tables[0];
Mydatalist.DataBind();
}
protected void Mydatalist_ItemCommand(object source, DataListCommandEventArgs e)
{
Panel pn = (Panel)e.Item.FindControl("mypane");
pn.Visible = false;
if (e.CommandName == "reply")
{
pn.Visible = true;
}
}
}
You have to programmably hide it. THe DataList should have an items property, and as such you can loop through all items, find the panel control using FIndControl, and set its visibility to false.
EDIT: So you need to do:
private void HideItems()
{
foreach (var item in this.dl.Items)
{
var panel = item.FindControl("mypane") as Panel;
if (panel != null)
panel.Visible = false;
}
}
In ItemCommand, call this method to hide all the existing control's panels.

Resources