I wanted to make an ascx usercontrol “lazy” load when it´s loading on aspx page. So I´m really using the ascx as a view (if you know about MVC you´ll get that) that only acts when it receives data.
So the thing I was after was something like…
The user makes a choice of a customer from a dropdown on the main page like:
That makes the view go into “lazy loading” mode showing the updateprogress as shown above.
And finally when the data has been loaded the control shows the data, like so:
So how did I do that?
In an ascx usercontrol I place the following markup:
<asp:UpdatePanel runat="server" ID="OrdersUpdatePanel" UpdateMode="Conditional"> <ContentTemplate> <asp:LinqDataSource runat="server" ID="OrdersDataSource" OnSelecting="OrdersDataSource_Selecting" /> <asp:GridView runat="server" ID="OrdersGridView" AutoGenerateColumns="false" ViewStateMode="Disabled" DataSourceID="OrdersDataSource" AllowPaging="true" AllowSorting="true" PageSize="3"> <Columns> <asp:BoundField HeaderText="ShipName" SortExpression="ShipName" DataField="ShipName" /> <asp:BoundField HeaderText="City" SortExpression="City" DataField="City" /> <asp:BoundField HeaderText="Address" SortExpression="Address" DataField="Address" /> <asp:BoundField HeaderText="Ship Via" SortExpression="Via" DataField="Via" /> </Columns> <PagerSettings Mode="Numeric" /> </asp:GridView> <asp:Timer runat="server" ID="LazyLoadTimer" Enabled="false" Interval="1" OnTick="LazyLoadTimer_Tick" /> </ContentTemplate> </asp:UpdatePanel> <asp:UpdateProgress runat="server" AssociatedUpdatePanelID="OrdersUpdatePanel" DisplayAfter="0"> <ProgressTemplate> <div> Loading orders please wait... </div> </ProgressTemplate> </asp:UpdateProgress>
Things to notice here is the asp:Timer control, here is where the magic happens. Another thing to notice is that I disable the ViewState (using VS 21010 if you are wondering about the “new” syntax), otherwise the paging won´t work as expected on the GridView. (I spent a few hours on that I can tell you).
In the code behind I have the following code:
IEnumerable<Order> datasource; Customer customer; protected void Page_Load(object sender, EventArgs e) { } public Customer Customer { set { this.customer = value; LazyLoadTimer.Enabled = true; } } protected void OrdersDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e) { if (datasource == null) { e.Cancel = true; return; } e.Result = (from o in datasource orderby o.ShippedDate select new { ShipName = o.ShipName, City = o.ShipCity, Address = o.ShipAddress, Via = o.ShipVia }).ToArray(); OrdersUpdatePanel.Update(); } protected void LazyLoadTimer_Tick(object sender, EventArgs e) { if (datasource == null) { System.Threading.Thread.Sleep(2000); // fake long running operation datasource = customer.Orders; OrdersGridView.DataBind(); } LazyLoadTimer.Enabled = false; }
Things to notice here is that when the view (ascx) receives the data (the Customer setter property) I enable the Timer which makes it go into the Tick event which shows the updateprogess since it is an async event. In that method I load up that data from the customer (via customer.Orders) and finally I databind the GridView which in turn calls to the selecting event which can now deal with the Linq expression I´m using to bind my data.
The final thing is to push data into my view, which is made from the page like:
if (Page.IsPostBack) { var customer = CustomerRepository.Instance.FindById(CustomerDropDownList.SelectedValue); OrdersForCustomerUserControl.Customer = customer; }
Note: The data comes from the Northwind database and I’m using the new EntityFramework 4.0…works like a charm!
#1 by Nickole Salotti on March 9, 2011 - 01:16
I just want to mention I’m new to blogging and certainly enjoyed this blog site. Very likely I’m want to bookmark your website . You surely have good well written articles. Appreciate it for sharing with us your website.