I was added the DataPager Control inside Listview. There is no problem while displaying the data. But When I click the Next page button I m getting error.
Error: The Select operation is not supported by ObjectDataSource 'ObjectDataSource2' unless the SelectMethod is specified.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
FillGrid();
}
private void FillGrid()
{
User user = new User();
user = (User)HttpContext.Current.Session["login"];
ObjectDataSource2.SelectMethod = "GetDetails";
ObjectDataSource2.SelectParameters.Add("Customer_ID", DbType.Int32, Convert.ToString(user.Customer_ID));
ObjectDataSource2.SelectParameters.Add("Selected_Period", DbType.String, Convert.ToString(Request.QueryString["period"]));
ObjectDataSource2.TypeName = "Online.Lib.Invoice";
}
CodeBeside:
<asp:ListView ID="ListView1" runat="server" DataSourceID="ObjectDataSource2">
<LayoutTemplate>
<asp:DataPager ID="DataPager1" PagedControlID="ListView1" runat="server">
<Fields>
<asp:NumericPagerField ButtonCount="10" />
<asp:NextPreviousPagerField FirstPageText="İlk" LastPageText="Son" NextPageText="İleri" PreviousPageText="Geri" />
</Fields>
</asp:DataPager>
</LayoutTemplate>
</asp:ListView>
Ok. Your FillGrid() works well and you can load it's data by the Page_Load routine. When you click "Next page" of the ListView, you're doing a PostBack.
if(!IsPostBack)
FillGrid();
}
..Which means FillGrid() aren't loaded (which is the place ObjectDataSource have it's Select instruction). That's out of what I can see in the code snippets above. Quite common to make such mistakes in IsPostBack handling.
Related
I have an aspx page using listview. The delete button I have needs to execute a sql delete using an ID found in the list view.
ASPX:
<asp:ListView runat="server" ID="ListView2" OnItemDataBound="ListView2_ItemDataBound" OnItemCommand="ListView2_ItemCommand">
<LayoutTemplate>
...
<asp:DataPager runat="server" ID="DataPager" PageSize="10" OnPreRender="DataPager_PreRender">
<Fields>
...
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
...
<td runat="server" align="right" colspan="4"><asp:Button ID="deleteRButton" CssClass="Button" runat="server" Text="Delete" CommandName="deleteRButton" OnClientClick="return confirm('You are about to delete this forum response. Are you sure you want to proceed?');" /></td>
...
</ItemTemplate>
<ItemSeparatorTemplate>
</ItemSeparatorTemplate>
</asp:ListView>
Code Behind:
protected void ListView2_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "deleteRButton") //Never makes it here with breakpoints
{
...
//Find label value and execute SQL
}
}
How do I get the button click to execute the Item Command code? I have tried using an OnClick method as well (which fires) but I don't have access to the label ID value that way.
EDIT:
Sharing page load event:
protected void Page_Load(object sender, EventArgs e)
{
GetQuestions(); //builds data table and binds to listview 1
GetAnswers(); //builds data table and binds to listview 2
questionIDBreadCrumb.Text = grabID(); //grabs id from url
//loads the current userID
getUserData();
}
SOLUTION:
Putting the page load events inside if (!ispostback) solved the issue.
if (!IsPostBack)
{
GetQuestions();
GetAnswers();
questionIDBreadCrumb.Text = grabID();
//loads the current userID
getUserData();
//validates questionOwner
}
I created my gridview with checkboxes inside of it with this code.
<asp:GridView ID="GridView1" runat="server" Width="366px" autogeneratecolumn="false">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="SelectAllCheckBox" runat="server" AutoPostBack="true" oncheckedchanged="SelectAllCheckBox_OnCheckedChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="EachCheckBox" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I tried check/uncheck it.
enter link description here
protected void SelectAllCheckBox_OnCheckedChanged(object sender, EventArgs e)
{
String test = "test";
test = "newtest";
GridView1.DataSource = null;
GridView1.DataBind();
}
But it doesn't trigger any event.
enter link description here
I'm trying to find where my code is missing and searched so far but still can't.
Thank you for your help!
You must use OnItemCreated or OnItemDataBound and link your checkbox with your delegate
void Item_Created(Object sender, DataGridItemEventArgs e)
{
CheckBox cbx = (CheckBox)e.Item.FindControl("SelectAllCheckBox");
cbx.CheckedChanged += SelectAllCheckBox_OnCheckedChanged;
}
The code looks fine and works for me.
I suspect you might be binding the GridView on every postback.
When you click the CheckBox with the event attached it causes the page to refresh. If you bind the CheckBox on Page_Load (or any method that occurs on every trip to the server) it will bind the grid every time you click the CheckBox. In this case it will never get as far as firing your event.
If so, try checking for a postback before binding your GridView.
For example:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Gridview1.DataSource = myDataSource;
GridView1.DataBind();
}
}
I am using ASP.NET 4.0 with C# (Visual Web Developer 2010 Express).
I have successfully managed to implement a simple GridView bound to a stored procedure data source using declarative ASP.NET code as shown here:
<asp:GridView
ID="grdTrades"
runat="server"
DataKeyNames="tradeId"
EnablePersistedSelection="true"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="false"
DataSourceID="sdsTrades"
>
<Columns>
<asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
<asp:BoundField DataField="tradeId" HeaderText="TradeId" ReadOnly="True" SortExpression="tradeId" />
< ... more columns ... >
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdsTrades" runat="server"
ConnectionString="<%$ ConnectionStrings:TradesDB %>"
ProviderName="<%$ ConnectionStrings:Trades.ProviderName %>"
SelectCommand="usp_GetTrades" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
It works great including paging and sorting. I want to remove the SqlDataSource and use code-behind (I'm trying to put database access code in one place). So far I have this in my code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
grdTrades.SelectedIndex = 0;
DBUtil DB = new DBUtil();
grdTrades.DataSource = DB.GetTrades();
grdTrades.DataKeyNames = new string[] { "tradeId" };
grdTrades.DataBind();
}
}
// this is needed otherwise I get "The GridView 'grdTrades' fired event PageIndexChanging which wasn't handled."
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.PageIndex = e.NewPageIndex;
grdTrades.DataBind();
}
My declarative code now looks like:
<asp:GridView
ID="grdTrades"
runat="server"
EnablePersistedSelection="true"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="false"
OnPageIndexChanging="grdTrades_PageIndexChanging"
>
<Columns>
<asp:CommandField ShowSelectButton="true" ButtonType="Link" SelectText="Select" />
<asp:BoundField DataField="tradeId" HeaderText="TradeId" ReadOnly="True" SortExpression="tradeId" />
< ... more columns ... >
</Columns>
</asp:GridView>
The problem is when I click on a page number the page becomes blank. I would also like to implement sorting but would like to get the paging working first. Please help.
Thanks
You need to bind your GridView every time you change page.
For example:
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.DataSource = DB.GetTrades();
grdTrades.PageIndex = e.NewPageIndex;
grdTrades.DataBind();
}
My advice would be to store your results from DB.GetTrades() in the ViewState (or Cache) so you don't need to go to the database everytime you change page.
Sorting can become quite difficult when doing this, though.
You can always use an ObjectDataSource instead of a SqlDatasource. You can then point your ObjectDataSource to look at your DB.GetTrades() function. Sorting and Paging will work automatically.
Hope that helps.
You can create a method to for binding the grid view instead of Binding it again in Paging. By creating a method that binds the Grid View you can always call the method to Bind the grid view whenever you want.
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
BindgrdTrades();
}
private void BindgrdTrades()
{
DBUtil DB = new DBUtil();
grdTrades.DataSource = DB.GetTrades();
grdTrades.DataKeyNames = new string[] { "tradeId" };
grdTrades.DataBind();
}
}
void grdTrades_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
grdTrades.PageIndex = e.NewPageIndex;
BindgrdTrades();
}
}
I had to make my _PageIndexChanging counter to public (I'm so new at asp.net that I have no idea why it matters). The page would through an error saying it couldn't find the class. These posts were a great help to get paging working with otherwise near verbatim logic. Thanks to all the posters for taking the time to lay it out so clearly. Here's the code I ended up with:
public partial class Requests : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
BindgrdBuilds();
}
}
private void BindgrdBuilds()
{
// Link GridView to datasource
GridView1.DataSource = BuildData.getBuilddata();
// Bind SQLDataSource to GridView after retrieving the records.
GridView1.DataBind();
}
public void GridView1_PageIndexChanging(Object sender, GridViewPageEventArgs e)
{
// increment PageIndex
GridView1.PageIndex = e.NewPageIndex;
// bind table again
BindgrdBuilds();
}
}
I stuck with AutoGenerated columns, and I'm doing some row binding to my data on the cs page that I didn't include above, but here's my asp code for the GridView:
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:GridView ID="GridView1"
OnRowDataBound="GridView1_RowDataBound"
OnPageIndexChanging="GridView1_PageIndexChanging"
runat="server"
SelectedRowStyle-BackColor="Yellow"
AllowPaging="true"
AllowSorting="true"
PageSize = "20"
AutoGenerateColumns="true"
<-- table formatting code trimmed -->
</asp:GridView>
I hope someone else can make use of this info, this thread was a great, simple example to follow. Now that paging works it's time to get real fancy and come up with a new name for GridView1 :D
I'm having an issue where I have 2 DataPagers on the same page, linked to the same ListView. Everything works fine, except the "bottom" or 2nd pager doesn't seem to be working. The page numbers are generated, but clicking on them does nothing. If I copy the "bottom" pager above the "top" pager, then that pager will work, but the one below it doesn't. Seems a only the pager that comes first seems to work:
<asp:DataPager ID="dpPagerTop" runat="server" PagedControlID="lvOutput" QueryStringField="pageNumber">
<Fields>
<asp:NumericPagerField NextPageText="Next" PreviousPageText="Previous" />
</Fields>
</asp:DataPager>
<asp:DataPager ID="dpPagerBottom" runat="server" PagedControlID="lvOutput" QueryStringField="pageNumber">
<Fields>
<asp:NumericPagerField NextPageText="Next" PreviousPageText="Previous" />
</Fields>
</asp:DataPager>
<asp:ListView ID="lvOutput" runat="server" OnPagePropertiesChanged="lvOutput_PagePropertiesChanged">
<LayoutTemplate>
<asp:PlaceHolder id="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<%# Eval("Title") %>
</ItemTemplate>
</asp:ListView>
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
dpPagerTop.SetPageProperties(Request.QueryString["pageNumber"].ToString(), 25, false);
dpPagerBottom.SetPageProperties(Request.QueryString["pageNumber"].ToString(), 25, false);
lvOutput.DataSource = [datasource];
lvOutput.DataBind();
}
}
protected void lvOutput_PagePropertiesChanged(object sender, EventArgs e)
{
lvOutput.DataBind();
}
UPDATE:
After fooling around with this some more, I've determined that both pagers will work if SetPageProperties has the correct parameters. The first parameter should be the number to start the results and the second should be number of results to show. However, I am getting the wrong numbers to display. I have exactly 100 records and I want to display 25 results per page. If I hardcode:
dpPagerTop.SetPageProperties(25, 25, true);
dpPagerBottom.SetPageProperties(25, 25, true);
This should be the 2nd page of the results and the results show 26-50. However, the bottom pager doesn't work.
Now, if I hardcode:
dpPagerTop.SetPageProperties(26, 25, true);
dpPagerBottom.SetPageProperties(26, 25, true);
Both pagers work like the should, but the number of results go from 27-51.
Can anyone recreate this, it's driving me nuts?!?!?
UPDATE 2:
I think I got it to work by setting the page properties BEFORE binding to the ListView.
I had a similar problem with two datapagers on a page bound to one listview. the datapagers weren't synchronized with each - so changes to the top then bottom pagers would have the appearance of the pager not working. This method put them back on track:
protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
DataPager2.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
}
I think I have this figured out.
First from what I can tell you need to databind the listview before you set the page properties.
Secondly, I think you are misunderstanding the first parameter to the SetPageProperties method. It does not set the current page, it sets the first record on this page of data.
Here is the HTML I am using
<asp:DataPager ID="dpPagerTop" runat="server" PagedControlID="lvOutput" QueryStringField="pageNumber"
PageSize="2">
<Fields>
<asp:NumericPagerField NextPageText="Next" PreviousPageText="Previous" />
</Fields>
</asp:DataPager>
<asp:DataPager ID="dpPagerBottom" runat="server" PagedControlID="lvOutput" QueryStringField="pageNumber"
PageSize="2">
<Fields>
<asp:NumericPagerField NextPageText="Next" PreviousPageText="Previous" />
</Fields>
</asp:DataPager>
<asp:ListView ID="lvOutput" runat="server" OnPagePropertiesChanged="lvOutput_PagePropertiesChanged">
<LayoutTemplate>
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<a href="Donation.aspx" title="<%# Eval("Type") %>">
<%# Eval("id")%></a>
</ItemTemplate>
</asp:ListView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:LutheranAssistanceConnectionString %>"
SelectCommand="SELECT [Id], [RecipientId], [Type], [Reason] FROM [Donations]">
</asp:SqlDataSource>
Here is the code in the code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//bind the list view first
lvOutput.DataSource = SqlDataSource1;
lvOutput.DataBind();
//the first parameter of SetPageProperties is not the page number
//it is index of the first record on the page
//So we need to calculate the index based on the passed in page number.
int pageNumber = Convert.ToInt32(Request["pageNumber"]);
int recordNumber = pageNumber * dpPagerTop.PageSize;
//now set first record
dpPagerTop.SetPageProperties(recordNumber , 25, false);
dpPagerBottom.SetPageProperties(recordNumber , 25, false);
}
}
protected void lvOutput_PagePropertiesChanged(object sender, EventArgs e)
{
lvOutput.DataBind();
}
Hope this helps
I have a standart Page within my ListView control on the page, And the Pager is work, however in order to move to next list of items i required to click on pager link twice before it actually moves to next set of items.
The code for the pager is:
<asp:ListView ID="lv_LostCard" runat="server" DataKeyNames="request_id" EnableViewState="false">
<LayoutTemplate>
<table width="550" border="1" class="table">
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</table>
<asp:DataPager ID="lv_Books_Pager" runat="server" PageSize="10">
<Fields>
<asp:NextPreviousPagerField ShowFirstPageButton="false" ShowPreviousPageButton="true" ShowNextPageButton="false" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ShowFirstPageButton="false" ShowPreviousPageButton="false" ShowNextPageButton="true" ShowLastPageButton="false" />
</Fields>
</asp:DataPager>
</LayoutTemplate>
<ItemTemplate>
</ItemTemplate>
</asp:ListView>
and the Code behind is:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
getLostCardsList();
}
}
protected void getLostCardsList()
{
using(LostCardsManagementDataContext LostCard = new LostCardsManagementDataContext())
{
var getLostCardsList = from lc in LostCard.lostcard_request_cards
select lc;
lv_LostCard.DataSource = getLostCardsList;
lv_LostCard.DataBind();
}
Can somebody tell me what happening and how to fix it ?
Thanks in advance
I have problems with listview sincerely.
I found a solution related to your question which seems there is no other way to fix that.You need to call OnPreRender method to rebind your source to listview.
protected void listview_PreRender(object sender, EventArgs e)
{
getLostCardsList();//your method for binding
}
Be adviced, PreRender events called before your page is rendered.More clearly,if your page has a postback event will render again.That means you need to store your data into a server collection (i.e. Session).
DataBind in the PagePropertiesChanged event.
private void listview_PagePropertiesChanged(object sender, System.EventArgs e)
{
listview.DataBind();
}
Are you binding your listview in code? Make sure you are only doing that on non-postbacks.
You have turned off the viewstate on your ListView. Try it with the viewstate back on.