How to programmatically iterate through pages of a GridView - c#

I've created a wallboard application to display outstanding support calls for my ICT department. I've bound a number of gridviews to sqldatasources which execute a stored procedure. This is automated via asp.net ajax controls and partially refreshes the page/data every 30 seconds.
At the moment, when the number of records in the gridview goes over 9, the gridview automatically pages and shows the number of pages in the bottom right hand corner. The helpdesk can then VNC to the box which controls the screen and manually click to see what's on the next page.
What I am after is a way to programmatically (using the c# code-behind file) changing the current displayed page after 10/15 seconds or so, obviously if this is possible in the scope of the gridview. I trailed using javascript (and failed at jquery) of scrolling the gridview within a div, however this didn't work as expected.
Can anyone point me in the right example? I can't find anyone else querying this functionality via a quick Google. Any help/advice of how to fix this issue would be greatly appreciated!!
Gridview Code:
<asp:GridView ID="GridView1" ShowHeader="False" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
GridLines="None" CellPadding="2" Font-Size="35pt" AllowPaging="True" PageSize="9">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID">
<ItemStyle Width="15%" />
</asp:BoundField>
<asp:BoundField DataField="ASSIGNEES" HeaderText="ASSIGNEES" SortExpression="ASSIGNEES">
<ItemStyle Width="32%" Wrap="false"/>
</asp:BoundField>
<asp:BoundField DataField="title" HeaderText="title" SortExpression="title">
<ItemStyle Width="53%" Wrap="false"/>
</asp:BoundField>
</Columns>
</asp:GridView>
SqlDataSource Code:
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:FPConnectionString %>" SelectCommand="HDMonitoringOutstandingToday" SelectCommandType="StoredProcedure"></asp:SqlDataSource>
Printscreen of wallboard:

You can try something like this in a timer.
if(GridView1.PageIndex == GridView1.PageCount)
{
GridView1.PageIndex = 0;
}
else
{
GridView.PageIndex = GridView.PageIndex + 1;
}
I cant remember if you would need to add one to the PageIndex or not.
But anyway, the properties you need to work with are PageIndex and PageCount.

GridView.PageIndex
You can change pages by setting the PageIndex, how you do it is up to you see here for some examples: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.pageindex.aspx

Related

How to display dynamically generated images in asp.net gridview?

I have a class (POCO) that has an Image property. I use a List<> of this class as the datasource for a gridview control. Most of the properties are grabbed from the database. However, I am dynamically generating a barcode (System.Drawing.Image) in my code behind and populating the Image property in the POCO with the result prior to databinding. It is NOT possible for me to store the images on the database or the filesystem. How do I go about displaying the barcodes in the Gridview control? When I try, nothing shows and the images generate 404 errors. The code for the gridview is:
<asp:GridView runat="server" ID="gvInventoryDetail" CssClass="centerpage"
style="width: 700px;" ItemType="DisplayModels.InventoryDetailItem"
DataKeyNames="InventoryId" AutoGenerateColumns="False"
AllowPaging="True" PageSize="11" ShowHeaderWhenEmpty="True">
<Columns>
<asp:BoundField HeaderText="Barcode" DataField="Barcode"/>
<asp:TemplateField HeaderText="Image">
<ItemTemplate >
<asp:Image ID="BarcodeImage" runat="server"
Height="150px" Width="80px" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="Comments" DataField="Comments"/>
<asp:BoundField HeaderText="Status" DataField="Status"/>
<asp:BoundField HeaderText="Broken?" DataField="IsBroken"/>
</Columns>
<SelectedRowStyle BackColor="#89d8f6" Font-Bold="True"/>
</asp:GridView>
Any help is MUCH appreciated!
I had a similar issue when generating pie charts using another 3rd party project.
What I did was the following:
Keep the Image Tag in your Grid.
Set that Image Tag to call an ASPX Page in your site, passing what ever params you need on the URL to generate the barcode image.
In that new ASPX do the following
response.clear()
response.binarywrite() of the image.
If you browse that URL you will see the image in the browser, which means, that URL would also show the image in your Image Tag in your grid.

GridView display more then 1000 rows

I use GridView to display data from DB. First I query data from DB to list<list<string>>, sort use linq, copy this array to DataTable and bind DataTable to GridView. But if in DataTable more then 1000 rows - it works very long or not works (error in browser).
How to fix this?
UPDATE i use rowspan in columns and create a delete buttons to all rows, and if i use paging wiil it works?
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" OnDataBinding="GridView1_DataBinding" OnRowDeleted="GridView1_RowDeleted" OnRowDeleting="GridView1_RowDeleting" >
<Columns>
<asp:BoundField DataField="Number" ItemStyle-Width="200px" > <ItemStyle Width="200px" > </ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Name" ItemStyle-Width="200px" > <ItemStyle Width="200px" > </ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="Nameoid" ItemStyle-Width="200px" > <ItemStyle Width="200px" > </ItemStyle>
</asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="Button2" runat="server" Text="Button" OnClientClick="return DeleteConfirm();" OnClick="Button2_Click" />
<asp:HiddenField ID="HiddenField2" runat="server" Value='<%#Bind("Number") %>' />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
It seems like you are doing lots of server side code in one round trip time. You should make it lesser so that page could show the result in grid view.
Here are few things on which you should work:
There is no need to store first in list then data table and then sorting. You can directly use the DATAVIEW class to sort the result from DB.
I think you should not display all 1000 record in grid view in a single page. You should use PAGING in grid view. This is also in built functionality of grid view by this you can show number of record in a one grid view page as you want..
For reference how to do this there is complete example. Follow the below link
http://www.dotnetgallery.com/kb/resource12-How-to-implement-paging-and-sorting-in-aspnet-Gridview-control.aspx
UPDATE:
If you want to delete a row in gridview with a link button on each row. Then follow the below article
enter link description here
You can put the UpdatePanel outside of gridview. First try to use the above code (from link), then try to add update panel. If you feel any difficulties ask here.
My suggestion would be to use Lazy loading pattern with your GridView .
You can refer to :
LazyLoadUpdatePanelusingTimerControlAJAX
or you can implement custom paging
Custompaging
You can use paging in your grid view having grid size of say 10,20,30 to accommodate large amount of data so that the page doesn't crash.
Try referring to this example
http://www.codeproject.com/Articles/106678/Display-Large-Amount-of-Data-in-GridView-with-Sear

Selection of checkboxes lost during pagination of gridview

I have a problem in gridview, as per requirement i have set No of Records per page = 4 in gridview. I have to select Checkbox against every complaint but problem is then when i got to next pge in gridview and e.g fro 1 to 2 then when i come back to page 1 then it doesn't show TICK in check boxes . It doesn't remember my selection when i browse to and back to page.
<asp:GridView ID="GridViewSmsComplaints" AllowPaging="True" PageSize="4" runat="server" AutoGenerateColumns="False" CssClass="mGrid" BorderColor="#333333" Width="550px" OnPageIndexChanging="GridViewSmsComplaints_PageIndexChanging" >
<Columns>
<asp:BoundField HeaderText="ID" DataField="ID" />
<asp:BoundField HeaderText="Recieving Date" DataField="RecievingDate" />
<%--<asp:BoundField HeaderText="ToMobileNo" DataField="ToMobileNo" /> --%>
<asp:BoundField HeaderText="FromMobileNo" DataField="FromMobileNo" />
<asp:BoundField HeaderText="Message" DataField="Message" >
<ItemStyle Wrap="True" />
</asp:BoundField>
<asp:TemplateField HeaderText="IsComplaint">
<ItemTemplate>
<asp:CheckBox ID="ckboxIsComplaint" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsComplaint").ToString()) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
please check the above link.here your problem was clearly explained here.i think so it may be helpfull
As per comments...
If you do not update the underlying database by processing the OnCheckChanged event of the check box, then it will simply be reading the same data all the time.
From How to add event for Checkbox click in Asp.net Gridview Column, I have extracted the required information and tried to modify to fit your initial question.
<asp:TemplateField HeaderText="IsComplaint">
<ItemTemplate>
<asp:CheckBox ID="ckboxIsComplaint" runat="server" Checked='<%# Convert.ToBoolean(Eval("IsComplaint").ToString()) %>' OnCheckedChanged="chk_CheckedChanged" AutoPostBack="true/>
</ItemTemplate>
</asp:TemplateField>
add checkbox change event in aspx.cs page
protected void chk_CheckedChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
<your data source>.Rows[row.DataItemIndex]["B"] = ((CheckBox)GridViewSmsComplaints.Rows[row.RowIndex].FindControl("ckboxIsComplaint")).Checked;
}

ASP.NET Gridview Buttons

I have a Gridview with 3 columns (CompanyName, Volume, counter) I would like to have the counter column be all buttons and when a user clicks the button it increments the counter by 1. I'm not sure how to properly setup the update command. Here is what I have so far:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"
EmptyDataText="There are no data records to display.">
<Columns>
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName"
SortExpression="CompanyName" />
<asp:BoundField DataField="Volume" HeaderText="Volume"
SortExpression="Volume" />
<asp:ButtonField DataTextField="counter" HeaderText="counter"
ButtonType="button"/>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:LiquorStoreConnectionString1 %>"
ProviderName="<%$ ConnectionStrings:LiquorStoreConnectionString1.ProviderName %>"
SelectCommand="SELECT [CompanyName], [Volume], [counter] FROM [Company]">
</asp:SqlDataSource>
All I need it to do is increment by 1 every time the button is pressed on that specific row.
You can try this:
... UpdateCommand="Update COMPANY SET counter=#Counter +1 WHERE CopmanyName=#Company"
<columns>
<asp:BoundField HeaderText="counter" DataField="Counter" />
</columns>
Make sure you have the bound field names correct.
I haven't tested to see if this + 1 works with a bound field. If it does not, then we'll have to use OnRowCommand to update the database manually, then you can re-bind the view and see updated counter. More importantly, I don't see a nice primary key for your Company so you can do the update... So my sample is using the CompanyName, and that is danger danger.
do you want to update the database?
You can catch the button click event in gridview row command .
Take a look at link given below
http://msdn.microsoft.com/en-us/library/bb907626.aspx

Gridview header issue: call event on header

Now I got this gridview, And I need the headers to be clickable, whereafter an event starts (something like OnClickHeader="header_ClickEvent"?) Ofcourse there is a SortExpression element, which enables to sort the grid, but I want to be able to start any event, like when clicking a button.
I could not find any solution within the asp:BoundField nor asp:TemplateField...
I thought a hyperlink could solve the problem, but that was a bit premature.
Also, when using a TemplateField, I find it very hard to fill the column with data.
Could anyone bring me the solution?
The Gridview:
<asp:GridView CssClass="gridview" ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="Student_key" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" PagerSettings-Visible="false" PageSize="14">
<HeaderStyle CssClass="headerstyle" />
<RowStyle CssClass="rowstyle"/>
<AlternatingRowStyle CssClass="altrowstyle" />
<Columns>
<asp:BoundField DataField="Studentnumber" HeaderText="Studentnummer" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="Prefix" HeaderText="Voorletters" >
<HeaderStyle CssClass="header75" />
</asp:BoundField>
<asp:BoundField DataField="prename" HeaderText="Voornaam" SortExpression="Voornaam">
<HeaderStyle CssClass="header75" />
</asp:BoundField>
<asp:BoundField DataField="nickname" HeaderText="Roepnaam" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="insertion" HeaderText="Tussenvoegsel" >
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:BoundField DataField="surname" HeaderText="Achternaam">
<HeaderStyle CssClass="header100" />
</asp:BoundField>
<asp:CommandField SelectText="show results" ShowSelectButton="True" >
<HeaderStyle CssClass="header100" />
</asp:CommandField>
</Columns>
<EmptyDataTemplate >There are no results shown, please try again.</EmptyDataTemplate>
</asp:GridView>
Funny, I had the same problem today, and, like you, I found the above solution a bit much.
Here's something that I'm happy with.
First, you need to use the CSS Friendly Control adapters. There are a lot of other benefits to this if you're using a GridView and you have any class whatsoever. It is needed in this case because it adds the necessary classes to your header based on sorting properties, which ASP.NET does not.
You don't need to change any of your code to add the adapters, just drop their DLL in your bin folder, and their .browser file in your App_Browsers folder (which you may need to add for this purpose).
(On a side node, I actually found that the adapters broke some of my other control layouts (which were styled against the default ASP.NET markup), so I ripped out all the adapter tags except the one for GridView.)
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.GridView"
adapterType="CSSFriendly.GridViewAdapter" />
</controlAdapters>
</browser>
Now, to get to the good part. This bit of jQuery in your document.ready event will have the desired effect.
// Make the entire column header clickable, not just the text
$('#your-table thead th.sortable').each( function() {
var href = $('a', this).attr('href');
$(this).click( new Function(href.replace(/^javascript:/, '')) );
$('a', this).attr('href', 'javascript: return false;');
});
Basically, it strips the javascript out of the link that ASP.NET places in the header, which looks like this
Qty
and puts the code into the header's click event. Then it disables the link, so that the event bubbling does not cause a conflict.
Of course, you'll need to add style rules to give the desired visual cues.
This solution degrades well, since those mythical non-javascript browsers will simply exhibit the default behavior (where you have to click on the header text).
Hope this works for you!
EDIT: I just realized that I hadn't read your question very carefully the first time. My code was designed to get the default sorting behavior when you click anywhere in the header (not just the link text). But I guess this was close enough :)
By the way, to get data into a template field similar to what ASP.NET would put there, you just add
<ItemTemplate>
<%# Eval("FieldName") %>
</ItemTemplate>
See the documentation on formatting, etc.
This is old code mind you. It can be optimized.
http://weblogs.asp.net/rajbk/archive/2006/08/04/Clickable-GridView-Headers.aspx

Categories

Resources