Два высокоразвитых элемента управления MultiView и Wizard позволяют организовать для пользователя имитацию сложного многостраничного просмотра. Они содержат встроенные средства локальной навигации, обеспечивающие смену кадров с разным пользовательским интерфейсом, но единым оформлением.
Элемент управления MultiView позволяет организовать страницу в виде множества вкладок. Каждая вкладка может содержать свой пользовательский интерфейс и обеспечивать свою форму представления одной и той же информации пользователя.
В результате оболочка сгенерирует следующий дескрипторный код
<%@ Page AutoEventWireup="true" CodeFile="MultiViewControl.aspx.cs" Inherits="MultiViewControl" Language="C#" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:MultiView ID="MultiView1" runat="server"> <asp:View ID="View1" runat="server"> </asp:View> <asp:View ID="View2" runat="server"> </asp:View> <asp:View ID="View3" runat="server"> </asp:View> </asp:MultiView></div> </form> </body> </html>
Замечание. Представления View можно добавлять и программно по мере необходимости (как и любой другой элемент управления). Для этого нужно создать экземпляр (например, View1 ) нового представления и добавить ссылку на него в коллекцию Views экземпляра (например, MultiView1 ) элемента MultiView с помощью MultiView1.Views.Add(View1) или MultiView1.Views.AddAt(index, View1). Свойство Views определено в классе System.Web.UI.WebControls.ViewCollection, который и имеет указанные методы Add() и AddAt(). Но мы будем для простоты использовать декларативный способ этапа проектирования.
Web-форма в оболочке после наших действий будет иметь вид
Visual Studio 2005 во время проектирования показывает все представления View в раскрытом виде, но на этапе выполнения на странице может отображаться только одно из них, которое раскроет пользователь. Каждое представление можно редактировать в оболочке точно также, как любую часть обычной страницы.
Будет ли при загрузке страницы раскрыто какое-либо представление или нет, определяется свойством MultiView.ActiveViewIndex, доступном и на этапе проектирования и программно. Если значение этого свойства равно "-1", то при начальной загрузке страницы ни одна из вкладок не будет раскрыта. Если свойство установлено в ноль, то будет раскрыта первая вкладка и т.д.
Давайте продолжим выполнение нашего примера и наполним представления каким-нибудь содержимым.
Как один из вариантов управления вкладками можно дать пользователю раскрывающийся список, с помощью которого он будет выбирать нужное представление.
Дескрипторное представление страницы будет таким
<%@ Page AutoEventWireup="true" CodeFile="MultiViewControl.aspx.cs" Inherits="MultiViewControl" Language="C#" %> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Элемент управления множеством представлений</title> </head> <body> <form id="form1" runat="server"> <div> <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"> </asp:DropDownList><br /> <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0"> <asp:View ID="View1" runat="server"> <h1>Мое фото</h1> <asp:Image ID="Image1" runat="server" ImageUrl="~/MyPhoto.jpg" /> </asp:View> <asp:View ID="View2" runat="server"> <h1>Мои стихи</h1> <p> У Лукоморья дуб зеленый<br /> Златая цепь на дубе том<br /> И днем и ночью кот ученый<br /> Все ходит по цепи кругом </p> </asp:View> <asp:View ID="View3" runat="server"> <h1>Мой календарь</h1> <asp:Calendar ID="Calendar1" runat="server" BackColor="#C0FFFF" BorderColor="Red" BorderStyle="Ridge"> </asp:Calendar> </asp:View> </asp:MultiView> </div> </form> </body> </html>
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class MultiViewControl : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { // Заполняем список только при первом запросе страницы, // а потом все будет сохраняться в состоянии вида. // Иначе список всегда будет переустанавливаться в начало if (!IsPostBack) { // Подсоединяем коллекцию с вкладками к списку DropDownList1.DataSource = MultiView1.Views; // Назначаем идентификатор, значениями которого // будут заполнены поля "Text" списка DropDownList1.DataTextField = "ID"; // Заполняем список подсоединенными данными DropDownList1.DataBind(); // Отображаем первое представление MultiView1.ActiveViewIndex = 0; // Синхронизируем список DropDownList1.SelectedIndex = 0; // Выделяем текущую дату Calendar1.SelectedDate = DateTime.Now.Date; Calendar1.SelectedDayStyle.BorderStyle = BorderStyle.Solid; } } // Обработчик события выбора в списке protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { MultiView1.ActiveViewIndex = DropDownList1.SelectedIndex; } }
В обработчике события Page_Load() мы, для тренировки, вставили код, чтобы при первом запросе страницы список программно заполнялся значениями атрибутов ID представлений. Этого можно и не делать, если вручную на этапе проектирования заполнить свойство Items списка более осмысленными именами.
Мы, также, назначили для списка AutoPostBack="True", чтобы он индивидуально осуществлял обратную отсылку. Ну, а если на странице будет много интерфейсных элементов с возможностью постинга, которые должен будет настроить пользователь. В этом случае будет расточительно, что каждый элемент интерфейса при настройке индивидуально посылает страницу на сервер для обновления. Лучше предусмотреть отдельную кнопку, которая отдаст команду броузеру на обратную отсылку после настройки всех интерфейсных элементов. Выполним эти модификации на новой странице.
Обратите внимание, что файл кода .cs автоматически копируется и переименовывается вместе со страницей. Более того, в оболочке даже не предусмотрена возможность переименовать его отдельно, пока он связан со страницей. Правда, его можно скопировать отдельно, тогда он переименовывается.
Сейчас мы должны заполнить список декларативно (на этапе проектирования).
Ничего не происходит, пока в списке мы не выбирем новый пункт. Только после этого свойство MultiView1.ActiveViewIndex примет отличное от -1 значение и представления при обратной отсылке начнут работать. Чтобы исправить это, нужно код присвоения значения свойству ActiveViewIndex переместить в обработчик нажатия кнопки.
Мы видим, что оболочка создала код заготовки JavaScript -сценария, который мы должны заполнить и который страница готова посылать на клиентский броузер. Чтобы не вникать в JavaScript приведем в свое оправдание аргумент, что поддержка сценариев JavaScript - дело ненадежное, поскольку пользователь может в своем броузере ее отключить.
В результате код файла будет таким
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class MultiViewControl : System.Web.UI.Page { // Обработчик события на кнопке Submit1 protected void Submit1_ServerClick(object sender, EventArgs e) { MultiView1.ActiveViewIndex = DropDownList1.SelectedIndex; } }
Теперь по прибытию на сервер обратной отсылки система ASP.NET распознает присланное событие щелчка на кнопке. Свойству MultiView1.ActiveViewIndex в обработчике события кнопки присваивается значение выбранной пользователем опции списка. Клиенту страница отправляет содержимое вкладки, соответствующей его выбору.