Я использую ASP.NET MVC 2 и .Net 3.5 с Visual Studio 2008.
Хорошо, то, что я имею в виду под «навигацией по страницам типа мастера», это сайт, на котором у вас есть списокэтапы данного процесса или рабочего процесса.Существует какое-то визуальное обозначение, указывающее, на какой части сцены вы находитесь.Я уже реализовал эту часть (хотя она пахнет как хак) с помощью следующего:
css класс current обозначает активную страницу.класс css notcurrent обозначает неактивную страницу (то есть страницу, на которой вы не находитесь)
Я объявил следующий метод в классе с именем NavigationTracker.
public static String getCss(String val, String currView)
{
String result = String.Empty;
String trimmedViewName = currView.Substring(currView.LastIndexOf("/") + 1).Replace(".aspx", "");
if (val.ToLower().Equals(trimmedViewName.ToLower()))
result = "current";
else
result = "notcurrent";
return result;
}
У меня есть свои этапы в управлении, как это:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="TheProject.Models" %>
<link href="../../Content/custom.css" rel="stylesheet" type="text/css" />
<%
String currentView = ((WebFormView)ViewContext.View).ViewPath;
%>
<table width="100%">
<tr>
<td class="<%= NavigationTracker.getCss("LogIn",currentView)%>" style="width:18%;">Log In</td>
<td class="<%= NavigationTracker.getCss("YearSelect",currentView)%>" style="width:18%;">Year Section</td>
<td class="<%= NavigationTracker.getCss("GoalEntry",currentView)%>" style="width:18%;">Goals</td>
<td class="<%= NavigationTracker.getCss("AssessmentEntry",currentView)%>" style="width:18%;">Assessment</td>
<td class="<%= NavigationTracker.getCss("SummaryEntry",currentView)%>" style="width:18%;">Summary</td>
</tr>
</table>
******************* ЭТО ГДЕМне нужна помощь ***********
Чтобы дополнить этот процесс, я хотел бы создать пользовательский элемент управления, в котором есть только кнопки «Предыдущая» и «Следующая» для управления этим процессом.Пока что одна загвоздка, с которой я столкнулся, заключается в том, что этот элемент управления нельзя поместить на главную страницу, но его необходимо включить в каждое представление, прежде чем форма закроется.Я не против этого.Нажав кнопку «Предыдущий» или «Далее», отправьте содержащую форму для соответствующего действия;однако я не уверен, как сделать следующее:
1) Определить, была ли нажата кнопка «Предыдущий» или «Следующий». 2) Показать / скрыть логику кнопок «Предыдущий» и «Следующий» в начале и конце процесса соответственно..
Еще одна странность, которую я замечаю с моим приложением в целом, заключается в том, что после прохождения нескольких страниц процесса, если я нажимаю кнопку "Назад", некоторые значения из моей модели заполняются на странице, а другие нет.,Например, текст, введенный для текстовой области, показывает, но значение, которое было выбрано для радиокнопки, не выбирается, однако при непосредственном осмотре модели соответствующий объект имеет значение, которое должно быть связано с радиокнопкой.
Возможно, мне просто нужно поместить эту последнюю часть в новый вопрос.Мой главный вопрос здесь с управлением навигацией.Любые указатели или советы по работе с этой логикой и обнаружению нажатия Next или Previous будут наиболее полезными.
EDIT 1
У меня была мысль поставить скрытое полев элементе управления, который отображает кнопки «Предыдущий и следующий».В зависимости от того, какая кнопка была нажата, я бы использовал JavaScript для обновления значения скрытых полей.Теперь проблема заключается в том, что скрытое поле никогда не создается и не отправляется вместе с формой.Я изменил аргументы поста контроллера, чтобы принять дополнительное поле, но оно никогда не отправляется, как и в FormCollection.
Вот код для скрытого поля.Обратите внимание, что он генерируется в пользовательском элементе управления, который вызывается внутри формы в родительском представлении (надеюсь, это имеет смысл).
<% Html.Hidden("navDirection", navDirection); %>
Мысли?
РЕДАКТИРОВАТЬ 2
Я решил все эти проблемы.Я опубликую код подробно во вторник самое позднее.Решение, представленное ниже, вероятно, будет выбрано в качестве ответа, поскольку это привело меня к правильному мыслительному процессу.
Короче говоря, решение заключалось в том, чтобы иметь класс Navigation, подобный классу, предложенному с логикой для определения следующей или предыдущей страницы на основе текущего представления и списка строк всех представлений.Частичное представление / пользовательский элемент управления были созданы для отображения кнопок «Предыдущая / Следующая».Пользовательский элемент управления имеет 2 скрытых поля: 1) одно со значением текущего представления 2) поле, указывающее направление навигации (предыдущее или следующее).JavaScript использовался для обновления значения скрытого поля навигации в зависимости от того, какая кнопка была нажата.Логика в пользовательском элементе управления определяет, отображать или нет кнопки «Предыдущий» или «Следующий» в зависимости от первого и последнего представлений в мастере по сравнению с текущим представлением.
Все сказано, я довольнодоволен результатами.Я, вероятно, найду некоторые проблемы с запахом кода, когда вернусь к этому, но пока это работает.
Спасибо всем за вашу помощь!
РЕДАКТИРОВАТЬ 3 - РЕШЕНИЕ
Вот код для элемента управления, который я построил для отображения кнопок навигации «Далее» и «Предыдущий»:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%@ Import Namespace="Project.Models" %>
<link href="../../Content/custom.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" >
function setVal(val) {
var nav = document.getElementById("NavigationDirection");
nav.value = val;
}
</script>
<%
String currentView = ((WebFormView)ViewContext.View).ViewPath;
String navDirection = "empty";
currentView = NavigationTracker.getShortViewName(currentView);
%>
<input type="hidden" value="<%= currentView %>" name="CurrentView" id="CurrentView" />
<input type="hidden" value="<%= navDirection %>" name="NavigationDirection" id="NavigationDirection" />
<% if( currentView != NavigationTracker.FirstPage) { %>
<div style="float:left;">
<input type="submit" value="Previous" onclick="setVal('previous')" /> <!-- On click set navDirection = "previous" -->
</div>
<% } %>
<% if (currentView != NavigationTracker.LastPage)
{ %>
<div style="float:right;">
<input type="submit" value="Next" onclick="setVal('next')" /> <!-- On click set navDirection = "next" -->
</div>
<% } %>
Оттуда вы визуализируете элемент управления непосредственно перед закрывающим тегом формы в представлениях, которые вам нужны, например:
<% Html.RenderPartial("BottomNavControl"); %>
<% } %>
Теперь я не могу опубликовать весь код NavigationTracker, но суть того, как он работает, может быть выведена из выбранного ответа и следующего фрагмента, который возвращает имя представления на основе текущего представления и направления. (предыдущий или следующий).
public String NextView
{
get
{
if (String.IsNullOrEmpty(this.NavigationDirection)) return string.Empty;
int index = this.MyViews.IndexOf(this.CurrentView);
String result = string.Empty;
if (this.NavigationDirection.Equals("next") && (index + 1 < MyViews.Count ))
{
result = this.MyViews[index + 1];
}
else if (this.NavigationDirection.Equals("previous") && (index > 0))
{
result = this.MyViews[index - 1];
}
return result;
}
}
Теперь выполнение всего этого имеет несколько побочных эффектов, которые можно легко считать запахом кода. Во-первых, мне нужно изменить все методы контроллера, помеченные [HTTPPOST], чтобы они принимали объект NavigationTracker в качестве параметра. Этот объект содержит вспомогательные методы и свойства CurrentView & NavigationDirection. Как только это будет сделано, я могу получить следующий вид одинаково во всех моих действиях:
return RedirectToAction(nav.NextView);
где nav имеет тип NavigationTracker.
Еще одно замечание: свойства FirstPage и LastPage в NavigationTracker являются статическими, поэтому я фактически использую NavigationTracker.FirstPage в моем файле global.asax.cs для своей маршрутизации. Это означает, что я могу перейти к своему классу NavigationTracker и изменить поток в одном месте для всего приложения.
Буду рад любым комментариям или критике этого решения. Я признаю, что это не может быть потрясающим решением, но на первый взгляд, я очень доволен этим.
Надеюсь, это поможет.