ASP.NET AJAX: используем закладки и браузерную кнопку 'Назад' - Добавляем точку истории когда пользователь сортирует табличную сетку (Grid)

ОГЛАВЛЕНИЕ

 

Добавляем точку истории когда пользователь сортирует табличную сетку (Grid)

Давайте расширим возможности нашего примера и сохраним точку истории при любой сортировке табличной сетки. Тем самым, каждый раз, когда пользователь решит отсортировать табличную сетку, браузер запишет новое состояние истории, а также обновится строка запроса в URL браузера, включая в себя информацию о состоянии (это позволяет создать закладку на страницу). С записью точек истории при любой сортировке сетки пользователь может отсортировать таблицу по цене (Price), далее - по названию (Name), а затем - по номеру товара (ProductID). Если при просмотре сетки, отсортированной по номеру товара (ProductID), пользователь нажмет на кнопку Back, от будет возвращен на страницу с сеткой, отсортированной по названию (в отличие от случая, когда пользователь возвращен на страницу, посещенную до данной). Код, который можно закачать в конце данной статьи, включает в себя страницу ASP.NET, названную BehaviorWithHistory.aspx, которая реализует данную функциональность.

Как я уже говорил ранее, нам необходимо сделать 3 вещи при использовании возможности хранения истории в ASP.NET AJAX:

  1. Решить, какие действия вызывают создание вставки точки истории.
  2. Добавитьточку истории при любом выполнении действия из пункта #1.
  3. Создать обработчик для события Navigate из ScriptManager, которое восстанавливает состояние в тот момент, когда пользователь нажимает кнопку Back (Назад) или Forward (Вперед), либо когда он открывает страницу, используя закладку.
Мы уже выполнили пункт #1 - мы решили записывать историю при любой сортировке элемента GridView. Когда сортируется GridView, вызывается событие Sorting. Нам нужно создать обработчик для события Sorting для того, чтобы создать точку истории.

Точка истории добавляется путем вызова AddHistoryPoint класса ScriptManager. Данный метод требует наличия строки, которая описывает текущее состояние. Данная строка будет использована позже в обработчике события Navigate из ScriptManager для того, чтобы восстановить состояние приложения при достижении страницы путем нажатия кнопок Back или Forward, либо из закладки. Так как мы строим нашу точку истории на критерии примененной сортировки, свойства GridView SortExpression и SortDirection определяют данное состояние. Вследствие этого, нам нужно передать значения данных свойств в метод AddHistoryPoint.

Следующий код демонстрирует как мы кодируем состояние GridView и добавляем его как точку истории.

protected void gvProducts_Sorting(object sender, GridViewSortEventArgs e)
{
   // Создаем состояние истории
   MyScriptManager.AddHistoryPoint("SortExpression", e.SortExpression);
   MyScriptManager.AddHistoryPoint("SortDirection", e.SortDirection.ToString());

   Page.Title = GetPageTitle(e.SortExpression, e.SortDirection);
}

Заметьте, что для каждой вещи, которую я хочу хранить в состоянии, я вызываю метод AddHistoryPoint, путем передачи "названия" для состояния и его значение. В вышеизложенном коде я регистрирую две детали в состоянии, названные "SortExpression" и "SortDirection" и соответственно сортирую значения e.SortExpression и e.SortDirection.

После сохранения состояния мы обновляем заголовок страницы. Метод GetPageTitle создает и возвращает подходящий заголовок, переданный в значениях SortExpression и SortDirection. Например, при сортировке колонки с ценами (UnitPrice) по возрастающей, метод GetPageTitle возвращает строку "Viewing Products Sorted by Price (Ascending)" (Просмотр товаров, отсортированных по цене). Данное значение  назначено свойству Title объекта Page. (Для получения более детальной информации по настройке заголовка страницы ASP.NET  - читайте статью "Динамическая настройка заголовка страницы").

Если мы посещаем страницу, используя данный код, то каждый раз при сортировке  табличной сетки URL адресная строка браузера обновляется и теперь включает в себя строку запроса, которая содержит информацию о состоянии. Посмотрите на адресную строку в следующем изображении. Когда страница BehaviorWithHistory.aspx посещается впервые, ее URL , как и ожидалось, содержит только BehaviorWithHistory.aspx.


Но как только табличная сетка сортируется, строка запроса обновляется и теперь включает в себя закодированную информацию о состоянии. Также доступна кнопка Back (Назад). В нижеприведенном изображении демонстрируется табличная сетка отсортированная по цене (Price) в порядке возрастания, и URL в адресной строке теперь содержит: BehaviorWithHistory.aspx#&&+2toRdN1TcuXKFN4BhNSqrMXMtnAEvRpZEk2MUzyrUhoPiJPO4mIypwAP9J+s7VtZ+uMZ0ub2iUXY5KDMgwufg==.

{mosimage}

Хотя кнопкаBack (Назад) теперь доступна, при нажатии мы не возвращаемся в предыдущее состояние сетки, где она не была отсортирована по цене (Price). Мы так и остаемся на странице BehaviorWithHistory.aspx, но таблицаужеотсортирована по цене. Это происходит потому, что нам еще предстоит осуществить последний шаг #3 - который заключается в создании обработчика для события Navigate элемента управления ScriptManager. При посещении страницы пользователем, обработчик события Navigate  вызывается либо при нажатии кнопок Back (Назад) или Forward (Вперед), либо при использовании закладки. Также обработчик ответственен за обработку сайта согласно строке запроса.

protected void MyScriptManager_Navigate(object sender, HistoryEventArgs e)
{
   if (!string.IsNullOrEmpty(e.State["SortExpression"]))
   {
      string sortExpressionFromState = e.State["SortExpression"];
      SortDirection sortDirectionFromState = (SortDirection)Enum.Parse(typeof(SortDirection), e.State["SortDirection"]);

      // Сортируем сетку согласно информации о сортировке, хранящийся в состоянии истории
      gvProducts.Sort(sortExpressionFromState, sortDirectionFromState);

      Page.Title = GetPageTitle(sortExpressionFromState, sortDirectionFromState);
   }
   else
   {
      // Сортируем сетку по названию товара (ProductName) в порядке возрастания
      gvProducts.Sort("ProductName", SortDirection.Ascending);

      Page.Title = GetPageTitle("ProductName", SortDirection.Ascending);
   }
}

Обработчик события Navigate начинает с проверки того, передано ли ожидаемое состояние. Если да, то оно извлекает значения из состояния истории (т.е. e.State), сортирует GridView и обновляет заголовок страницы. Если информация о состоянии не была передана, то оно возвращается в значение по умолчанию - таблица отсортирована по колонке с названием товара (ProductName) в порядке возрастания.

И это все! Используя данный код, кнопки Back (Назад) и Forward (Вперед)  работают, как положено. Более того, пользователь может установить закладку на веб-странице после сортировки по какой-то определенной колонке. Когда пользователь возвращается на данную страницу при помощи закладки, GridView загрузит и автоматически отсортирует по соответствующей колонке.