ASP.NET
17.03.2014
Pag.1/33
ASP.NET MasterPage Pagini de continut o interactiune cu clasa MasterPage o setare pagini master in mod dinamic o pagini master inlantuite
SiteMap TreeView Menu ASP.NET AJAX
Bibliografie:
Matthew MacDonald, Mario Szpuszta: Pro ASP.NET 3.5 in C# 2008 – Second Edition
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.2/33
Master page
ASP.NET defineste doua tipuri specializate de pagini: master page pagini de continut O pagina master este un template de pagina si poate contine orice combinatie de HTML, controale web si chiar cod. Master page pot include regiuni predefinite ce pot fi modificate ulterior : locul unde va fi plasat un continut. Fiecare pagina de continut (content page) referentiaza o singura pagina master si poate adauga continut in regiunile predefinte de aceasta. Exemplu
Pagina master poate folosi controlul ContentPlaceHolder ce identifica regiunea din cadrul paginii unde poate fi adaugat continut. Un control ContentPlaceHolder poate fi definit in sectiunea si altul in sectiunea ce permite paginii obisnuite ce foloseste acest master page sa insereze continutul propriu. Untitled Page My Site Copyright © 2008.
Pentru a folosi master page trebuie sa construim o pagina de continut ce are ca template aceasta pagina. Directiva Page contine atributul MasterPageFile. Vezi exemplul de mai jos.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.3/33
Pagina definita mai sus nu poate contine elemente cum ar fi : , , si , aceasta va contine un control Content care este in relatie biunivoca cu controalele ContenPlaceHolder definite in MasterPage. Acest lucru inseamna ca pentru fiecare control ContentPlaceHolder definit in master page trebuie sa existe in control Content definit in pagina obisnuita, referirea se face prin ContentPlaceHolderID definit in pagina obisnuita. Exemplu. SimpleContentPage foloseste ca master page ~/SiteTemplate.master ce are definit
ContentPlaceHolder=”ContentPlaceHolder1”. In aceasta pagina folosim ContenPlaceHolderID=”ContenPlaceHolder1” pentru a plasa continut. Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun.
Master Pages cu Table si Layout CSS
Exemplu ( cod partial in master page): My Header Navigation Controls My Footer
Ce layout defineste? R: Un tabel cu trei randuri pentru: header, content si footer. Acelasi efect (vizualizare) se poate obtine daca definim master page sub forma urmatoare la care atasam un fisier de stiluri. Cod partial din master page :
...
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.4/33
...
Descriere in fisierul de stiluri (.css)
.leftPanel { position: absolute; top: 70px; left: 10px; width: 150px; } .rightPanel { position: absolute; top: 70px; right: 10px; width: 150px; } .centerPanel { margin-left: 151px; margin-right: 151px; padding-left: 12px; padding-right: 12px; }
Mai mult despre pagini master interactiune cu clasa MasterPage ; setare pagini master in mod dinamic; pagini master inlantuite ;
Interactiune cu clasa MasterPage
Probleme: - sa avem acelasi continut pe fiecare pagina – continutul inclus in master page; - sa avem continut diferit pe fiecare pagina – folosim ContentPlaceHolder. Scenariu: Presupunem ca dorim ca o pagina master sa ne ofere posibilitatea de afisare in moduri diferite a paginilor ce folosesc acest template. Posibilitatile de realizare sunt descrise in continuare. Accesarea instantei paginii master (obiect MasterPage) curente se face folosind proprietatea Page.Master care este R/O. Se pot seta proprietati pe obiectul MasterPage obtinut astfel. Adaugarea unei proprietati sau metode publice la clasa paginii master. Pagina ce foloseste acest obiect MasterPage va putea accesa ceea ce am definit.
Ioan Asiminoaei
ASP.NET
Page.Master returneaza un obiect
17.03.2014
Pag.5/33
generic MasterPage, deci trebuie facut cast la obiectul
nostru. protected void Page_Load(object sender, EventArgs e) { SiteTemplate master = (SiteTemplate)Master; master.BannerText = "Content Page #1"; }
Alta posibilitate de a obtine acces la tipuri din MasterPage este de a adauga directiva MasterType la pagina de continut ce foloseste master page.
In acest caz putem scrie direct in cod: protected void Page_Load(object sender, EventArgs e) { Master.BannerText = "Content Page #1"; }
Observatie Cand navigam de la o pagina la alta toate obiectele pagini-web sunt recreate si ca atare nu putem presupune ca am setat o proprietate intr-o pagina si o vom regasi in alta pagina. Trebuie folosite mecanismele de comunicare dintre pagini (de ex. cookie). Alta posibilitate de a accesa controale individuale din MasterPage este data de folosirea metodei FindControl() din clasa MasterPage.
Label lbl = Master.FindControl("lblTitleContent") as Label; if (lbl != null) { lbl.Text = "Content Page #1"; }
Setarea in mod dinamic a paginii master
Se foloseste proprietatea Page.MasterPageFile ce returneaza fisierul ce defineste pagina master pentru pagina de continut curenta. Codul trebuie pus in tratatrea evenimentului Page.Init, adica metoda Page_Init().
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.6/33
Pagini master imbricate
O pagina master poate folosi o alta pagina master. Definirea se face astfel: Prima pagina master Untitled Page The Root
A doua pagina master ce foloseste prima pagina master. The Second Level
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.7/33
Navigare in Website
Transferare client de la o pagina la alta. Metoda cea mai la indemana este folosirea unui link la pagina dorita. In afara de aceasta metoda, ASP.NET are un sistem de navigare preconstruit si care consta din : Controale MultiView si Wizard. Modelul harta site (site map) – ce permite definirea structurii de navigare a site-ului si asocierea directa la controale avansate. Controale de navigare avansate – TreeView si Menu.
Pagini cu vizualizari multiple
Dorim sa oferim vizualizari multiple pentru aceeasi informatie si sa permitem utilizatorului sa treaca de la o vizualizare la alta (grid sau chart de exemplu) fara a parasi pagina.
Controlul MultiView
Se pot declara mai multe vizualizari si sa afisam numai una la un moment dat. Creare MultiView : tag si adaugare tag pentru fiecare vizualizare. ... ... ...
In interiorul tag-ului adaugam HTML sau controale web. Showing View #1 Showing View #2 Text content. Showing View #3
Pentru a preciza ce vizualizare va fi folosita vom folosi proprietatea MultiView.ActiveViewIndex ce are ca valoare implicita -1 (nu se afiseaza nimic). Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.8/33
Exemplu ce asociaza lista de vizualizari la un DropDownList. protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DropDownList1.DataSource = MultiView1.Views; DropDownList1.DataTextField = "ID"; DropDownList1.DataBind(); } }
Codul ce seteaza vizualizarea poate fi: protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { MultiView1.ActiveViewIndex = DropDownList1.SelectedIndex; }
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.9/33
Comenzi preconstruite pentru navigare Controlul MultiView include o serie de comenzi preconstruite pentru a realiza navigarea de la o pagina la alta. Ceea ce trebuie sa facem este sa adaugam butoane la View si sa asociem comenzile potrivite. Ex.
sau
Sincronizarea intre vizualizarea curenta si DropDownList de mai inainte poate fi facuta in cod astfel (se trateaza evenimentul ActiveViewChanged): protected void MultiView1_ActiveViewChanged(object sender, EventArgs e) { DropDownList1.SelectedIndex = MultiView1.ActiveViewIndex; }
Nume comanda
Camp MultiView
Descriere
PrevView PreviousViewCommandName NextView NextViewCommandName SwitchViewByID SwitchViewByIDCommandName ID (string name). ID este luat din proprietatea CommandArgument a butonului. SwitchViewByIndex SwitchViewByIndexCommandName
Harta site
Ce ofera ASP.NET pentru navigare intre pagini? Sunt oferite urmatoarele posibilitati: Modalitate de a defini structura de navigare a site-ului. Este un fisier XML ce contine harta site-ului. Parsare fisier harta site si convertire informatii intr-un model obiect. Acest lucru este realizat de controlul SiteMapDataSource si XmlSiteMapProvider. Modalitate de a folosi informatia din harta site-ului pentru a afisa pozitia curenta a utilizatorului si de a-i oferi posibilitatea sa treaca de la o pagina la alta. Acest lucru se realizeaza cu ajutorul controalelor asociate controlului SiteMapDataSource.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.10/33
Definire harta site
E nevoie de un furnizor al hartii de navigare dat de XmlSiteMapProvider care citeste informatia dintr-un fisier XML. XmlSiteMapProvider cauta un fisier cu numele Web.sitemap in radacina directorului virtual. Cu informatiile din acest fisier se creaza obiectul SiteMap ce va fi disponibil altor controale prin intermediul SiteMapDataSource. Trebuie construit fisierul Web.sitemap si definita structura site-ului folosind elementele si .
Acest lucru poate fi facut din mediul de dezvolatare adaugand un articol de tip Site Map. Structura acestui fisier este : ... ... ...
Un contine un singur care poate la randul sau sa contina mai multe elemente . Fiecare nod din harta site-ului ar trebui sa aiba un titlu, o descriere si un URL :
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.11/33
Observatie Nu putem crea doua noduri in harta site-ului ce au acelasi URL.
Asocierea la o harta site
Structura ce urmeaza este definita intr-o pagina master.
Apoi putem crea o pagina astfel: Default.aspx page (home).
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.12/33
Singurul lucru pe care mai trebuie sa-l facem este sa alegem controalele ce vor fi folosite pentru a afisa harta site-ului. In exemplu se alege un control TreeView si il asociem la SiteMapDataSource in cadrul master page, folosind DataSourceID :
Putem folosi si un control de tip Menu:
Rezultatul este:
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.13/33
Clasa SiteMapPath poate fi folosita pentru a arata utilizatorului locatia curenta si a-i permite sa navigheze sus in ierarhie. Controlul se defineste in pagina master.
Ioan Asiminoaei
ASP.NET Proprietate ShowToolTips ParentLevelsDisplayed PathDirection PathSeparator
17.03.2014 Descriere
Pag.14/33
Numarul maxim de niveluri ce va fi vizualizat. Implicit -1 = toate. Doua valori: RootToCurrent (implicit) si CurrentToRoot. Indica caracterele folosite ca separatori intre fiecare nivel. Implicit >.
Vizualizarea unei portiuni din harta site-ului Nu se afiseaza nodul radacina
SiteMapDataSource.ShowStartingNode=false;
Harta site-ului arata astfel: ...
Ioan Asiminoaei
ASP.NET Start din nodul curent
17.03.2014
Pag.15/33
Se seteaza proprietatea SiteMapDataSource.StartFromCurrentNode la true.
Controlul TreeView combinat
cu si .
iar crearea in mod programabil:
TreeNode newNode = new TreeNode("Software"); // Add as a child of the first root node // (the Products node in the previous example). TreeView1.Nodes[0].ChildNodes.Add(newNode);
TreeView afiseaza toate nodurile implicit. Putem controla acest aspect cu ajutorul proprietatii TreeViewExpandDepth. Proprietatea MaxDataBindDepth (implicit -1 : toate) da posibilitatea de a seta cate niveluri in tree vor fi afisate. Desfasurare / restrangere nod : TreeNode.Expand = true(false);
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.16/33
TreeNode
Fiecare nod este reprezentat de un obiect TreeNode. Proprietati : ChildNodes Parent. Alte proprietati Text ToolTip Value NavigateUrl SelectedNodeChanged – eveniment Target numai daca NavigateUrl este setat. ImageUrl ImageToolTip Un exemplu cu TreeView si selectie nod. protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { // Fill a DataSet with two DataTable objects, representing // the Products and Categories tables. DataSet ds = GetProductsAndCategories(); // Loop through the category records. foreach (DataRow row in ds.Tables["Categories"].Rows) { // Use the constructor that requires just text // and a nondisplayed value. TreeNode nodeCategory = new TreeNode( row["CategoryName"].ToString(), row["CategoryID"].ToString()); TreeView1.Nodes.Add(nodeCategory); // Get the children (products) for this parent (category). DataRow[] childRows = row.GetChildRows(ds.Relations[0]); // Loop through all the products in this category. foreach (DataRow childRow in childRows) { TreeNode nodeProduct = new TreeNode( childRow["ProductName"].ToString(), childRow["ProductID"].ToString()); nodeCategory.ChildNodes.Add(nodeProduct); } // Keep all categories collapsed (initially). nodeCategory.Collapse();
Ioan Asiminoaei
ASP.NET
} } }
17.03.2014
Pag.17/33
Selectare nod protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e) { if (TreeView1.SelectedNode == null) return; if (TreeView1.SelectedNode.Depth == 0) { lblInfo.Text = "You selected Category ID: "; } else if (TreeView1.SelectedNode.Depth == 1) { lblInfo.Text = "You selected Product ID: "; } lblInfo.Text += TreeView1.SelectedNode.Value; }
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.18/33
Populare noduri la cerere
Se foloseste proprietatea PopulateOnDemand setata pe true. Cand utilizatorul desfasoara o ramura din arbore, TreeView genereaza evenimentul
TreeNodePopulate iar in metoda atasata putem adauga noduri la TreeView.
Popularea poate fi facuta de pe partea clientului daca proprietatea
TreeView.PopulateNodesFromClient = true sau de pe partea de server , in caz
contrar. protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DataTable dtCategories = GetCategories(); // Loop through the category records. foreach (DataRow row in dtCategories.Rows) { TreeNode nodeCategory = new TreeNode( row["CategoryName"].ToString(), row["CategoryID"].ToString()); // Use the populate-on-demand feature for this // node's children. nodeCategory.PopulateOnDemand = true; // Make sure the node is collapsed at first, // so it's not populated immediately. nodeCategory.Collapse(); TreeView1.Nodes.Add(nodeCategory); } } }
Si acum codul din metoda atasata evenimentului TreeNodePopulate: protected void TreeView1_TreeNodePopulate(object sender, TreeNodeEventArgs e) { int categoryID = Int32.Parse(e.Node.Value); DataTable dtProducts = GetProducts(categoryID); // Loop through the product records. foreach (DataRow row in dtProducts.Rows) { // Use the constructor that requires just text // and a nondisplayed value. TreeNode nodeProduct = new TreeNode( row["ProductName"].ToString(), row["ProductID"].ToString()); e.Node.ChildNodes.Add(nodeProduct); } }
Un nod dat este populat numai o singura data. Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.19/33
Controlul Menu
Putem asocia sursa de date sau completa manual folosind obiecte MenuItem. Clasa MenuItem Proprietati Text ToolTip Value NavigateUrl Target Selectable ImageUrl Menu contine o colectie de obiecte MenuItem in proprietatea Items. MenuItem contine o colectie de obiecte ChildItems. protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { DataSet ds = GetProductsAndCategories(); // Loop through the category records. foreach (DataRow row in ds.Tables["Categories"].Rows) { // Create the menu item for this category. MenuItem itemCategory = new MenuItem( row["CategoryName"].ToString(), row["CategoryID"].ToString()); Menu1.Items.Add(itemCategory); // Create the menu items for the products in this // category. DataRow[] childRows = row.GetChildRows(ds.Relations[0]); foreach (DataRow childRow in childRows) { MenuItem itemProduct = new MenuItem( childRow["ProductName"].ToString(), childRow["ProductID"].ToString()); itemCategory.ChildItems.Add(itemProduct); } } } } protected void Menu1_MenuItemClick(object sender, System.Web.UI.WebControls.MenuEventArgs e) {
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.20/33
if (Menu1.SelectedItem.Depth == 0) { lblInfo.Text = "You selected Category ID: "; } else if (Menu1.SelectedItem.Depth == 1) { lblInfo.Text = "You selected Product ID: "; } lblInfo.Text += Menu1.SelectedItem.Value; }
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.21/33
ASP.NET AJAX
Introducere in ASP.NET AJAX ASP.NET AJAX consta din urmatoarele: cod pe partea clientului; cod pe partea de server. Codul de pe partea clientului este JavaScript. Partea de server din ASP.NET AJAX include controale si componente ce folosesc bibliotecile JavaScript de pe partea clientului. Trasaturi principale ASP.NET AJAX apel metode remote refresh partial al paginii controale preconstruite extensii limbaj JavaScript ASP.NET AJAX pe Client: Bibliotecile de Script Partea de client contine o colectie de fisiere JavaScript. Pentru ASP.NET 3.5 nu trebuie nimic special pe partea de client, in caz contrar trebuie descarcate fisierele de la adresa http://ajax.asp.net/downloads/default.aspx. Bibliotecile clientului sunt in System.Web.Extensions.dll si sunt folosite ca un script de resurse. Exemplu de script ce extrage biblioteca de script ASP.NET AJAX :
In fisierul de configurare vom avea: ...
Clasa ScriptResourceHandler examineaza argumentul pasat in “query string” si returneaza fisierul de script cerut.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.22/33
ASP.NET AJAX pe Server: ScriptManager ScriptManager este un control ce nu are un aspect vizual, face legatura la bibliotecile ASP.NET AJAX JavaScript. Se adauga la pagina din ToolBox.
Callback pe partea de server Exemplu Consideram o pagina cu doua controale DropDownList. Primul contine lista regiunilor iar al doilea afiseaza teritoriile din regiune. Al doilea DropDownList va fi completat dupa fiecare selectie realizata in primul DropDownList. Se va executa cod pe server.
In ASP.NET AJAX, callback-urile sunt totdeauna facute la o metoda separata, aflata pe partea de server – un serviciu web.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.23/33
Servicii Web in ASP.NET AJAX
Cand se executa un callback pe server cu ASP.NET AJAX, codul JavaScript de pe partea clientului apeleaza o metoda din serviciu web de pe partea de server. Un serviciu web este o colectie de metode de pe partea de server ce pot fi apelat remote de catre clienti. Pentru a apela un serviciu Web, clientul trimite o cerere HTTP. ASP.NET creaza obiectul serviciu web, ia parametrii din adresa data de URL, ruleaza codul din metoda, returneaza rezultatele si distruge obiectul serviciu web. Mesajel sunt bazate pe SOAP, dar in ASP.NET AJAX se foloseste JSON (JavaScript Object Notation).
Crearea serviciului Web
Serviciul web in ASP.NET AJAX consta din doua parti: un fisier .asmx ce actioneaza ca un endpoint; un fisier .cs ce contine codul C#. Adaugam aceste doua fisiere la site-ul ce contine pagina ASP.NET AJAX. Mod creare serviciu web in VS : Website -> Add New Item si alegem template Web Service. .asmx contine ceva de genul:
iar clasa din .cs
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] // pentru JSON public class TerritoriesService : System.Web.Services.WebService {...}
Creare metoda web
Atributul [WebMethod]
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] public class TerritoriesService : System.Web.Services.WebService { [WebMethod()] public void DoSomething()
Ioan Asiminoaei
ASP.NET
{ ... } }
17.03.2014
Pag.24/33
Pentru exemplul enuntat trebuie sa completam regiunile dintr-un teritoriu ales. Codul poate fi :
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.Web.Script.Services.ScriptService] public class TerritoriesService : System.Web.Services.WebService { [WebMethod()] public List GetTerritoriesInRegion(int regionID) { SqlConnection con = new SqlConnection( WebConfigurationManager.ConnectionStrings[ "Northwind"].ConnectionString); SqlCommand cmd = new SqlCommand( "SELECT * FROM Territories WHERE RegionID=@RegionID", con); cmd.Parameters.Add(new SqlParameter("@RegionID", SqlDbType.Int, 4)); cmd.Parameters["@RegionID"].Value = regionID; List territories = new List(); try { con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { territories.Add(new Territory( reader["TerritoryID"].ToString(), reader["TerritoryDescription"].ToString())); } reader.Close(); } catch (SqlException err)
{
// Mask errors. throw new ApplicationException("Data error."); } finally { con.Close(); } return territories; } } public class { public public public { Territory string ID; string Description; Territory(string id, string description) this.ID = id; this.Description = description; } public Territory() { } }
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.25/33
Apel serviciu web
Se adauga controlul ScriptManager la pagina dorita. Se adauga tag in cadrul acestui control.
ScriptManager genereaza proxy JavaScript pe care-l vom folosi pentru a face apeluri de metode. Linia de cod din JavaScript este:
TerritoriesService.GetTerritoriesInRegion(regionID, OnRequestComplete);
sau poate fi
TerritoriesService.GetTerritoriesInRegion(regionID, OnRequestComplete, OnError);
OnRequestComplete si OnError sunt functii JavaScript apelate cand cererea a fost executata complet sau in caz de eroare. Apelurile de pe partea de client sunt asincrone. Observati parametrii in plus la acest apel asincron. Ultima etapa consta in a adauga codul JavaScript ce apeleaza serviciul Web si trateaza rezultatul. E nevoie de cel putin doua functii : una pentru a initia callback si alta pentru a primi rezultatele. Initiere callbak (functia ce va fi apelata) : function GetTerritories(regionID) { TerritoriesService.GetTerritoriesInRegion(regionID, OnRequestComplete, OnError); }
iar in control
Functia OnRequestComplete():
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.26/33
function OnRequestComplete(result) { var lstTerritories = document.getElementById("lstTerritories"); lstTerritories.innerHTML = ""; for (var n = 0; n < result.length; n++) { var option = document.createElement("option"); option.value = result[n].ID; option.innerHTML = result[n].Description; lstTerritories.appendChild(option); } }
Functia pentru tratarea erorii poate fi: function OnError(result) { var lbl = document.getElementById("lblInfo"); lbl.innerHTML = "" + result.get_message() + ""; }
Plasare metoda web intr-o pagina
Acelasi cod de mai inainte plasat in fisierul .cs al paginii cu modificarile indicate in culoarea rosie: public partial class WebServiceCallback_PageMethods : System.Web.UI.Page { [System.Web.Services.WebMethod()] [System.Web.Script.Services.ScriptMethod()] public static List GetTerritoriesInRegion(int regionID) { // Farm the work out to the web service class. TerritoriesService service = new TerritoriesService(); return service.GetTerritoriesInRegion(regionID); } ... }
Se elimina tag din ScriptManager si se adauga: PageMethods.GetTerritoriesInRegion(regionID, OnRequestComplete);
Obiectul PageMethods expune toate metodele web adaugate la pagina curenta. In acest mod avem acces la valorile din view state si din controale.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.27/33
ASP.NET AJAX CALLBACKS SI SERVICII WCF Se aduga din VS. Acelasi concept.
Stop !
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.28/33
Controale server ASP.NET AJAX
Controalele ASP.NET AJAX emit scripturile ASP.NET AJAX de care au nevoie. Controalele ASP.NET 3.5 din aceasta categorie sunt : UpdatePanel, Timer si UpdateProgress. Aceste controale suporta actualizarea partiala.
UpdatePanel The UpdatePanel is a handy control that lets you take an ordinary page with server-side logic and make sure it refreshes itself in flicker-free Ajax style. The basic idea is that you divide your web page into one or more distinct regions, each of which is wrapped inside an invisible UpdatePanel. When an event occurs in an UpdatePanel that would normally trigger a postback, the UpdatePanel intercepts the event and performs an asynchronous callback instead. Here’s an example of how it happens: 1. The user clicks a button inside an UpdatePanel. 2. Some client-side JavaScript code (that has been generated by ASP.NET AJAX) intercepts the client-side click event and performs a callback to the server. 3. On the server, your normal page life cycle executes, with all the usual events. Finally, the page is rendered to HTML and returned to the browser. 4. The client-side JavaScript code receives the full HTML and updates every UpdatePanel on the page by replacing its current HTML with the new content. (If a change has occurred to content that’s not inside an UpdatePanel, it’s ignored.) The UpdatePanel control works in conjunction with the ScriptManager control. When using the UpdatePanel, you must be sure that the ScriptManager.EnablePartialRendering property is set to true (which is the default value). You can then add one or more UpdatePanel controls to your page. As you drag and drop controls in an UpdatePanel, the content appears in the section. Here’s an example of an UpdatePanel that contains a label and a button: The UpdatePanel is a template-based control. When it renders itself, if copies the content from its ContentTemplate into the page. As a result, you can’t dynamically add controls to the UpdatePanel using the UpdatePanels.Controls collection. However, you can insert controls dynamically using the UpdatePanels.ContentTemplateContainer.Controls collection. The UpdatePanel doesn’t derive from Panel. Instead, it derives directly from Control. The UpdatePanel has one role in life—to serve as a container for content that you want to refresh asynchronously.
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.29/33
Unlike the standard ASP.NET Panel, an UpdatePanel has no visual appearance and doesn’t support style settings. If you want to display a border around your UpdatePanel or change the background color, you’ll need to place an ordinary Panel (or just a static tag) in your UpdatePanel. On the page, the UpdatePanel renders itself as a tag. However, you can configure the UpdatePanel so it renders itself as an inline element by changing the RenderMode property from Block to Inline. For example, you could take this step when you want to create an UpdatePanel that wraps text inside a paragraph or some other block element. Figure 32-3 shows a sample web page that consists of three UpdatePanel controls (which have been highlighted using an off-white background color). Each UpdatePanel features the same content: a Label control and a Button control. Every time the page is posted to the server, the Page.Load event fills all three labels with the current time: protected void Page_Load(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToLongTimeString(); Label2.Text = DateTime.Now.ToLongTimeString(); Label3.Text = DateTime.Now.ToLongTimeString(); }
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.30/33
Conditional Updates If you have more than one UpdatePanel and each is completely self-contained, you can configure the panels to update themselves independently. Simply change the UpdatePanel.UpdateMode property from Always to Conditional. Now, the UpdatePanel will refresh itself only if you cause a postback by clicking a control in that UpdatePanel. So if you use this with the example in Figure 32-3, when you click a button, the label in that panel will be updated. The other panels will remain untouched. There’s an interesting quirk here. Technically, when you click the button all the labels will be updated, but only part of the page will be refreshed on the client side to show that fact. Most of the time, this distinction isn’t important. However, it can lead to possible anomalies because the new updated value of each label will be stored in view state. As a result, the next time the page is sent back to the server, the labels will all be set to their most recent values. Interrupted Updates There’s one caveat with the approach shown in the previous example. If you perform an update that takes a long time, it could be interrupted by another update. As you know, ASP.NET AJAX posts the page back asynchronously, so the user is free to click other buttons while the postback is under way. Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.31/33
ASP.NET AJAX doesn’t allow concurrent updates, because it needs to ensure that other information— such as the page view state information, the session cookie, and so on— remains consistent. Instead, when a new asynchronous postback is started, the previous asynchronous postback is abandoned. For the most part, this is the behavior you want. If you want to prevent the user from interrupting an asynchronous postback, you can add JavaScript code that disables controls while the asynchronous postback is under way. To do this, you need to attach an event handler to the beginRequest event, in the same way that you added an event handler to the endRequest event in the error handling example. Another option is to use the UpdateProgress control discussed later in this chapter. Triggers When you use conditional update mode, you have a few other options for triggering an update. One option is to use triggers to tell an UpdatePanel to render itself when a specific event occurs in a specific control on the page. Technically, the UpdatePanel always uses triggers. All the controls inside an UpdatePanel automatically become the triggers for the UpdatePanel. In the current example, you’ve seen how this works with nested buttons—when the Button.Click event occurs, an asynchronous postback takes place. However, it also works with the default event of any web control (as designated by the DefaultEvent attribute in that control’s code), provided that event posts back the page. For example, if you place a TextBox inside an UpdatePanel and set the TextBox.AutoPostBack property to true, the TextBox.TextChanged event will trigger an asynchronous postback and the UpdatePanel will be updated. Triggers allow you to change this behavior in two ways. For one, they allow you to set up triggers to link to controls outside the panel. For example, imagine you have this button elsewhere on your page: Ordinarily, this button would trigger a full postback. But by linking it to an UpdatePanel, you can change it to perform an asynchronous postback. To implement this design, you need to add an AsyncPostBackTrigger to the UpdatePanel that specifies the ID of the control you’re monitoring and the event that triggers the refresh:
The EventName attribute specifies the event you want to monitor. Usually, you don’t need to set this because you’ll be monitoring the default event, which is used automatically. However, it’s a good practice to be explicit. Now, when you click the cmdOutsideUpdate button, the click will be intercepted on the client
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.32/33
side, and the PageRequestManager will perform an asynchronous postback. All the UpdatePanel controls that have UpdateMode set to Always will be refreshed. All the UpdatePanel controls that have UpdateMode set to Conditional and have an AsyncPostBackTrigger for cmdOutsideUpdate will also be refreshed. You can use triggers in one other way. Instead of using them to monitor more controls, you can use them to tell the UpdatePanel to ignore certain controls. For example, imagine you have a button in your UpdatePanel. Ordinarily, clicking that button will trigger an asynchronous request and partial update. If you want it to trigger a full-page postback instead, you simply need to add a PostBackTrigger (instead of an AsynchronousPostBackTrigger). For example, here’s an UpdatePanel that contains a nested button that triggers a full postback rather than an asynchronous postback:
This technique isn’t as common, but it can be useful if you have several controls in an UpdatePanel that perform limited updates (and so use asynchronous postbacks) and one that performs more significant changes to the whole page (and so uses a full postback). Timed Refreshes with the Timer The previous section showed you how to refresh self-contained portions of the page. Of course, in order for this technique to work, the user needs to initiate an action that would ordinarily cause a postback, such as clicking a button. In some situations, you might want to force a full- or partial-page refresh without waiting for a user action. For example, you might create a page that includes a stock ticker, and you might want to refresh this ticker periodically (say, every 5 minutes) to ensure it doesn’t become drastically outdated. ASP.NET AJAX includes a Timer control that can help you implement this design. The Timer control is refreshingly straightforward. You simply add it to a page and set its Interval property to the maximum number of milliseconds that should elapse before an update. For example, if you set Interval to 60000, the timer will force a postback after one minute elapses. You can place the Timer anywhere on the page. It doesn’t need to be in an UpdatePanel. (In fact, your page doesn’t need to include any UpdatePanel controls.) The timer raises a server-side Tick event, which you can handle to update your page. However,
Ioan Asiminoaei
ASP.NET
17.03.2014
Pag.33/33
ou don’t necessarily need to use the Tick event, because the full-page life cycle executes when the timer fires. This means you can respond to other page and control events, such as Page.Load. The timer is particularly well suited to pages that use partial rendering, as discussed in the previous section. That’s because a refresh in a partially rendered page might just need to change a single portion of the page. Furthermore, partial rendering makes sure your refreshes are much less intrusive. Unlike a full postback, a callback with partial rendering won’t cause flicker and won’t interrupt the user in the middle of a task. To use the timer with partial rendering, wrap the updateable portions of the page in UpdatePanel controls with the UpdateMode set to Conditional, and add a trigger that forces an update whenever the timer fires: ...
All the other portions of the page can be left as is, or you can wrap them in conditional UpdatePanel controls with different triggers if you need to update them in response to other actions. To stop the timer, you simply need to set the Enabled property to false in server-side code. For example, here’s how you could disable the timer after ten updates: protected void Timer1_Tick(object sender, EventArgs e) { // Update the tick count and store it in view state. int tickCount = 0; if (ViewState["TickCount"] != null) { tickCount = (int)ViewState["TickCount"]; } tickCount++; ViewState["TickCount"] = tickCount; // Decide whether to disable the timer. if (tickCount > 10) { Timer1.Enabled = false; } }
Ioan Asiminoaei