The ListView is displaying properly and the DataPager is displaying the buttons at the bottom, but when I click the NEXT button, the DataPager is not going to the next page of data.
ASPX page:
<div id="EventListing">
<asp:ListView ID="ListEvents" runat="server">
<LayoutTemplate>
<div ID="itemPlaceholder" runat="server">
</div>
<div id="pagerFormat">
<asp:DataPager ID="ListingDataPager" runat="server" PageSize="5" PagedControlID="ListEvents" QueryStringField="page" >
<Fields>
<asp:NextPreviousPagerField
FirstPageText="First"
LastPageText="Last"
NextPageText="Next"
PreviousPageText="Back" />
</Fields>
</asp:DataPager>
</div>
</LayoutTemplate>
<ItemTemplate>
<table id="tblEvents">
<tr>
<td rowspan="4" id="Col1Events"></td>
<td rowspan="4" id="Col2Events"></td>
<td rowspan="4" id="Col3Events"></td>
<td class="tdEvents"><span style="font-weight:bold; font-size: 1em;"><%#Eval("EVENT_DATERANGE") %>: <%#Eval("EVENT_NAME") %></span></td>
</tr>
<tr>
<td class="tdEvents"> <span style="font-size: .9em;"><%#Eval("EVENT_DESC") %></span></td>
</tr>
<tr>
<td class="tdEvents"><span style="font-size: .9em;"><%#Eval("EVENT_STREET") %>, <%#Eval("CITY.CITY_NAME") %></span></td>
</tr>
<tr>
<td class="tdEvents"><span style="font-size: .9em;"><%#Eval("EVENT_PHONE") %></span></td>
</tr>
<tr>
<td colspan="4" id="tdEmpty"></td>
</tr>
</table>
</ItemTemplate>
</asp:ListView>
</div>
Code Behind Page:
protected void btnFindEvents_Click(object sender, EventArgs e)
{
DateTime StartDt;
string EventType = ddlEventType.SelectedValue;
string dt = Request.Form["DatePickername"];
if (ddlEventType.SelectedIndex == 0)
{
EventType = "";
}
if (dt != "")
{
StartDt = Convert.ToDateTime(Request.Form["DatePickerName"]);
}
else
{
StartDt = DateTime.Now;
}
string CityName= ddlEventCity.SelectedValue;
if (ddlEventCity.SelectedIndex == 0)
{
CityName = "";
}
if ((ddlEventType.SelectedIndex == 0) && (ddlEventCity.SelectedIndex == 0))
{
//(1) ALL EVENTS
BLgetEvents obj = new BLgetEvents();
var EventList = obj.getAllEvents(StartDt);
ListEvents.DataSource = EventList;
ListEvents.DataBind();
}
}
you have to bind data again on the ListView when you page by DataPager. So, you need to implement this bind on PagePropertiesChanging event of your ListView control. Something like:
// 1 - add a method to bind ListView, add some parameters if you need
protected void BindListView()
{
var data = // get data from database
ListEvents.DataSource = data;
ListEvents.DataBind();
}
// 2 - call this method on the button
protected void btnFindEvents_Click(object sender, EventArgs e)
{
BindListView();
}
// 3 - call this method on the PagePropertiesChanging event of the ListView
protected void ListEvents_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
//set current page startindex, max rows and rebind to false
YourDataPagerControlId.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
//rebind List View
BindListView();
}
And on your asp.net webform, you need to set the event on the listview tag:
<asp:ListView ID="ListEvents" runat="server" OnPagePropertiesChanging="ListEvents_PagePropertiesChanging">
...
</asp:ListView>
When you set the datasource from code behine, the same principle is valid for other databound controls like GridView, DataList, Repeater etc (you need to bind again on some paging event). An alternative way to solve this, you could add a datasource control (like objectdatasource, linqdatasource, etc...) and set it on the ListView's DataSourceID property and the DataPager will work automatically.
For more details, look at this link: http://weblogs.asp.net/hajan/archive/2011/09/08/paging-listview-using-datapager-without-using-datasource-control.aspx
Related
<form>
<asp:Repeater id="rptComments" runat="server">
<HeaderTemplate>
<table class="detailstable FadeOutOnEdit">
<tr>
<th style="width:200px;">Answers</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<th style="width:200px;"><asp:DropDownList ID="dropDownForChecklistAnswers" runat="server" /></th>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
<asp:Button id="button" text="Submit" OnClick="Page_Load" runat="server" />
</FooterTemplate>
</asp:Repeater>
</form>
Code Behind:
List<Checklist_Record_Choice> CLRC =
(from choice in db.Checklist_Record_Choices
select choice).ToList();
dropDownForChecklistAnswers.DataSource = CLRC;
DropDownList1.DataTextField = Text;//Text being the name of column2 in the table (which contains yes, no, n/a)
dropDownForChecklistAnswers.DataBind();
ERROR: dropDownForChecklistAnswers does not exist in the current context???
please advise
EDIT;
thanks for reply. I have
public void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
ClarkeDBDataContext db1 = new ClarkeDBDataContext();
List<string> CLRC =
(from choice in db1.Checklist_Record_Choices
select choice.Text).ToList();
DropDownList ddl = (DropDownList)e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = CLRC;
}
but DropDownList ddl is coming back as object ref not set to instance of an object...why is it null??
You need to use FindControl to access a control which is part of a Repeater's template.
Subscribe to the OnItemDataBound of the Repeater (set the attribute OnItemDataBound="OnReptDataBound")
And then in your code behind do the following
void OnReptDataBound(object sender, RepeaterItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item)
{
DropDownList ddl = (DropDownList )e.Item.FindControl("dropDownForChecklistAnswers");
ddl.DataSource = ....
Am not sure why I cannot access my Label control which was inside the Panel and the Panel is inside the DataList
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource1" Width="100%">
<ItemTemplate>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<!-- post details -->
<td style="width: 60%">
<asp:Panel ID="panelPostDetails" runat="server" CssClass="postpage_details">
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr>
<td colspan="2"><div class="postpage_header"><%# Eval("Heading") %></div></td>
</tr>
<tr>
<td>
<img src="picserver/posts/<%# Eval("ImagePath") %>/1.jpg" alt="preview" style="width: 240px;" />
<div id="morepictures">
<asp:Label ID="lblMorePictures" runat="server" />
</div>
</td>
<td>
<div style="padding: 0px 5px 0px 5px;">
<div>
more stuff here
</div>
</div>
</td>
</tr>
</table>
</asp:Panel>
<asp:RoundedCornersExtender ID="RoundedCornersExtender1" runat="server"
Radius="6"
Corners="All"
TargetControlID="panelPostDetails"></asp:RoundedCornersExtender>
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
but when I tried using "lbl" in Page_Load, it seems it cannot find the control? can you please help me?
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
Label l = p.FindControl("lblMorePictures") as Label;
l.Text = code;
that code returns Object reference not set to an instance of an object.
Thanks in advance
update:
ItemDataBound and Page_Load event
---------------------------------
Panel p = DataList2.FindControl("panelPostDetails") as Panel;
if(p==null)
{
System.Diagnostic.Debug.WriteLine("panel does not exist");
}
else
{
System.Diagnostic.Debug.WriteLine("panel does exist");
}
output:
panel does not exist
what on earth is going on!?!
Typically, you access controls like this at runtime by handling either the DataList's ItemCreated or ItemDataBound event. Here's a sample event handler:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item) {
Label lbl = (Label)e.Item.FindControl("panelPostDetails").FindControl("lblMorePictures");
lbl.Text = code;
}
}
Wire up your the event handler like this:
<asp:DataList ID="DataList2" runat="server" OnItemDataBound="DataList2_ItemDataBound" ...
#Peter's code must work.
you can also try this:
protected void DataList2_ItemDataBound(object sender, DataListItemEventArgs e)
{
string st= (e.Item.FindControl("lblMorePictures") as Label).Text;
}
and put breakpoint to wath to st. In my case I get a text of lblMorePictures.
With my Form View I needed to add CType to the FindControl. I understand DataList doesn't necessarily need the Ctype however it is possible the Panel may need this prefix. In this case frmDelView is the name of my Form View. In my case the code line below is in my PreRender of my form. That was the only place at the time of creating the form it would return the data I needed to pass to a label on a next page of a Wizard Step page. Long story.
Note: my code is vb and not C#. It should be nearly or exactly the same.
CType(frmDelView.FindControl("txtcboDAcct"), TextBox).Text
I know I've done something like this before, but I have no idea why it isn't working now. I have a ListView with some textboxes. I want to read the text out of those boxes when I click a button (linkbutton, whatever).
<asp:ListView runat="server" ID="lv_bar" EnableViewState="true">
<LayoutTemplate>
<table>
<tr>
<th>Foo</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton ID="lb_delete" CausesValidation="false" runat="server" Text="Del" /></td>
<td><asp:TextBox id="txt_foo" runat="server" /></td>
</tr>
</ItemTemplate>
</asp:ListView>
<asp:LinkButton ID="lb_add" CausesValidation="false" runat="server" Text="Add" />
And then here's the relevant code-behind stuff:
protected void Page_Load(object sender, EventArgs e)
{
lb_chapter_add.Click += lb_chapter_add_Click;
if (!IsPostBack)
{
lv_chapters.DataSource = new List<Foo>() { new Foo() { Name = "harbl"} };
lv_chapters.DataBind();
}
}
void lb_add_Click(object sender, EventArgs e)
{
foreach (ListViewDataItem item in lv_bar.Items)
{
var txt_foo = (TextBox)item.FindControl("txt_foo");
Response.Write("foo: " + txt_foo.Text);
}
Response.Write("<br />the end");
Response.End();
}
But what I see when I enter some text into txt_foo and click lb_add is just "the end". What am I doing wrong here?
The problem it that you are using a a non persistent object as DataSource.
Due to clicking the button, you generate a postback and lv_chapters does not contain any items. Set a breakpoint in the line where the foreach is and you will see that lv_chapters.Items in null, or that it's Count property returns 0.
I want to implement an apperance as this article mentioned using nested ListView control. However, in my scenario, I cannot use EntityDataSource control so I bind data manually.
My table:
Categories
PK: UniqueId, Guid
Name, string
ParentId, Guid
<asp:ListView ID="CategoryList" runat="server"
onitemdatabound="CategoryList_ItemDataBound">
<LayoutTemplate>
<table>
<asp:PlaceHolder ID="itemPlaceHolder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td colspan="2"><%# Eval("Name") %></td>
</tr>
</ItemTemplate>
</asp:ListView>
protected void Page_Load(object sender, EventArgs e)
{
using (PractiseEntities context = new PractiseEntities()) {
var result = from categories in context.Categories
select categories;
CategoryList.DataSource = result;
CategoryList.DataBind();
}
}
I want the sub category have an indent by add a <td> tag to the item which "ParentId" is not null. And my question is how to edit the generated html tags in the ItemDataBound event?
You could have something like this:
<ItemTemplate>
<tr>
<td colspan="2"><%# GetParentContent(Eval("ParentID")) %></td>
</tr>
</ItemTemplate>
in the code-behind:
protected string GetParentContent(object ParentID)
{
if(ParentID!=null)
... return parent HTML ...
else
return "";
}
Through CommandName="Delete" I try to delete a line from the ListView control but not from the datasource. On Pressing Delete I expect the webpage to reload and show me the updated ListView(with one line deleted). But nothing changes, the ListView will display the same content after pressing Delete. What do I do wrong?
<asp:ListView ID="ListView1"
DataSourceID="XmlDataSource1"
ItemContainerId="DataSection"
runat="server">
<LayoutTemplate>
<h3>Protocols to Upload...</h3>
<table border=0 style="background-color:#9C9EFF; width: 100%;">
<tr align=left>
<th>Region/Exam/Program</th><th>Protocol</th><th>Position</th>
</tr>
<asp:PlaceHolder ID="itemPlaceholder" runat="server"></asp:PlaceHolder>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr>
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton ID="SelectCategoryButton" runat="server" Text="Select" CommandName="Select"/>
</td>
</tr>
</ItemTemplate>
<SelectedItemTemplate>
<tr id="Tr1" runat="server" style="background-color:#F7F3FF">
<td><%#XPath("Location/Path")%></td>
<td><%#XPath("Location/Name")%></td>
<td><%#XPath("Location/Position")%></td>
<td style="width:40px">
<asp:LinkButton runat="server" ID="SelectCategoryButton" Text="Delete" CommandName="Delete" />
</td>
</tr>
</SelectedItemTemplate>
<%-- <ItemSeparatorTemplate>
<div style="height: 0px;border-top:dashed 1px #ff0000"></div>
</ItemSeparatorTemplate>--%>
</asp:ListView>
<asp:XmlDataSource ID="XmlDataSource1" XPath="HttpRequestBO/ProtocolsDTO/ProtocolDTO" runat="server"
DataFile="~/HttpRequestBo.Sample.xml"></asp:XmlDataSource>
And this is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ListView1_OnItemDeleted(Object sender, ListViewDeletedEventArgs e)
{
if (e.Exception != null)
{
e.ExceptionHandled = true;
}
}
protected void ListView1_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
ListView1.Items.Remove(dataItem);
}
}
If I don't use the e.ExceptionHandled = true;, after pressing the Delete link the web page will come up with a "Specified method is not supported." message. Why?
If I use the above mentioned line, then the page refreshes but I can still see all original lines (although on debugging I can see that the ListVieItem collection now only contains an item less.)
It's because of the DatasourceID parameter, which binds at every single postback on the original file.
What you should do is to bind your list on the first page load only. The delete button will work as you expect then.
--- after comments.
OK.
In fact, the Delete command would work if you had defined the Delete method on your datasource. Since that's not what you want, you must define the ItemCommand event handler
and tell it to remove the ListViewItem that issued the event.
protected void yourListView_OnItemCommand(object sender, ListViewCommandEventArgs e)
{
if (String.Equals(e.CommandName, "Delete"))
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
yourListView.Items.Remove(dataItem);
}
}
It will do so without touching the XML file beneath. Do not databind against it, else the "deleted" row will appear again.