Обмен информацией между страницами с содержимым (Content Pages) и мастер–страницами (Master Pages) - Передача информации от мастер-страницы (Master Page) к странице с содержимым

ОГЛАВЛЕНИЕ


Передача информации от мастер-страницы (Master Page) к странице с содержимым

В определенных случаях мастер-страница может содержать элемент управления, который, будучи обновленным пользователем, требует обновления определенной страницы. Например, может быть, мастер-страница содержит выпадающий список (DropDownList), который, будучи измененным, требует обновления страницы и вывода информации на основе выбранного пункта. Лично я думаю, что такая функциональность должна быть перенесена в отдельный пользовательский элемент управления (User Control) , и данный пользовательский элемент управления должен быть добавлен на соответствующие страницы с содержимым. Тем не менее, может случиться так, что потребуется передать информацию от мастер-страницы к странице с содержимым, так что стоит изучить данную технику.

Как уже говорилось, я настоятельно рекомендую не использовать сильное связывание между мастер-страницей и страницей с содержимым. Такого сильного связывания можно избежать путем разумного использования событий. Вкратце: мы можем создать мастер-страницу, которая вызывает событие в момент, когда происходит какое-либо действие на стороне мастер-страницы. Данное действие может передать дополнительную информацию, и затем страницы, которым необходима данная информация, могут "подписаться" на данное событие мастер-страницы.  (Другим подходом к данной ситуации, который не рассматривается в данной статье, является назначение страницей представителя свойства мастер-страницы. Несмотря на то что статья рассматривает пользовательские элементы управления и страницы ASP.NET, данные принципы применимы к мастер-страницам (пользовательский элемент управления) и к страницам с содержимым (страница ASP.NET).)

Чтобы продемонстрировать это, представьте, что у нас есть элемент DropDownList в мастер-странице. Когда в нем изменяется индекс, мы хотим оповестить страницу с содержимым об изменении для того, чтобы она могла соответственно обновить экран. Начните с создания элемента DropDownList с именем Moods на мастер-странице и затем создайте обработчик для события SelectedIndexChanged данного элемента. Далее, нам необходимо определить событие для мастер-страницы, указывающее подпись обработчика события. Обработчик события указывает, какие входные параметры были переданы обработчику события. Например, давайте передадим значения свойств Text и Value выбранной опции списка DropDownList. Тем самым мы можем использовать CommandEventHandler, передающий объект CommandEventArgs в обработчик события, включающий в себя свойства CommandName и CommandArgument, которые мы можем использовать для хранения выбранных значений свойств Text и Value из ListItem.

Чтобы определить событие, названное MoodChanged для мастер-страницы, использующей CommandEventHandler, примените следующий синтаксис:

' VB...
Partial Class MasterPageFiles_Main
   Inherits System.Web.UI.MasterPage

   Public Event MoodChanged As CommandEventHandler
End Class

// C#
public partial class MasterPageFiles_MainCS : System.Web.UI.MasterPage
{
   public event CommandEventHandler MoodChanged;
}

Когда сработает событие SelectedIndexChanged элемента DropDownList нам нужно будет вызвать событие MoodChanged. Для этого добавьте следующий код в обработчик события SelectedIndexChanged элемента DropDownList :

' VB...
Partial Class MasterPageFiles_Main
   Inherits System.Web.UI.MasterPage

   Public Event MoodChanged As CommandEventHandler

   Protected Sub Moods_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Moods.SelectedIndexChanged
      If Moods.SelectedIndex <> 0 Then
         RaiseEvent MoodChanged(Me, New CommandEventArgs(Moods.SelectedItem.Text, Moods.SelectedValue))
      End If
   End Sub

End Class

// C#
public partial class MasterPageFiles_MainCS : System.Web.UI.MasterPage
{
   public event CommandEventHandler MoodChanged;

   protected void Moods_SelectedIndexChanged(object sender, EventArgs e)
   {
      if (Moods.SelectedIndex != 0 && MoodChanged != null)
         MoodChanged(this, new CommandEventArgs(Moods.SelectedItem.Text, Moods.SelectedValue));
   }

}

Примечание: в C#(,) сначала нам необходимо удостовериться в том, что событие не равно null до того, как вызывать его (заметьте проверку "&& MoodChanged != null" в условии if). Ссылка события равняется null, если никто не "подписан" на данное событие... ...

Следующим шагом будет "подписывание" на событие в страницах, которые зависят от изменений в выпадающем списке DropDownList. Для того чтобы подписаться на событие, нам следует  программным путем указать в странице, что  в том  случае, когда срабатывает событие MoodChanged мастер-страницы, необходимо запустить определенный обработчик события. Следующий код демонстрирует способ установления данной связи между событием и обработчиком в C# и VB:

' VB...
Partial Class Demos_PassInfoToPage
   Inherits System.Web.UI.Page

   Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
      'Связываем событие (MoodChanged) с обработчиком (MoodChangedFromMasterPage)
      AddHandler Master.MoodChanged, AddressOf MoodChangedFromMasterPage
   End Sub

   Private Sub MoodChangedFromMasterPage(ByVal sender As Object, ByVal e As CommandEventArgs)
      Dim moodText As String = e.CommandName
      Dim moodValue As String = e.CommandArgument.ToString

      MoodChangedLabel.Text = String.Format("You have selected mood {0}, which has a value of {1}...", moodText, moodValue)
   End Sub

End Class

// C#
public partial class Demos_PassInfoToPageCS : System.Web.UI.Page
{
   protected void Page_Init(object sender, EventArgs e)
   {
      // Связываем событие (MoodChanged) с обработчиком (MoodChangedFromMasterPage)
      Master.MoodChanged += new CommandEventHandler(MoodChangedFromMasterPage);
   }

   private void MoodChangedFromMasterPage(object sender, CommandEventArgs e)
   {
      string moodText = e.CommandName;
      string moodValue = e.CommandArgument.ToString();

      MoodChangedLabel.Text = String.Format("You have selected mood {0}, which has a value of {1}...", moodText, moodValue);
}
}

Обработчик события Page_Init связывает событие MoodChanged с обработчиком события MoodChangedFromMasterPage (и должен переустановить данную связь при каждом постбэке). Заметьте, что свойство Master предоставляет строгий контроль типов. Это происходит потому, что я использовал директиву @MasterType в файле.aspx для данной страницы.