【发布时间】:2010-07-02 15:12:00
【问题描述】:
我在 Visual Studio 2008 中使用 ASP.NET MVC 2 和 .Net 3.5。
好的,我所说的“向导式页面导航”指的是一个网站,您可以在其中列出给定流程或工作流程中的阶段。有某种视觉符号来指示您处于阶段的哪个部分。我已经通过以下方式实现了这部分(尽管它闻起来像黑客):
css 类当前表示活动页面。 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 的指针或提示都会非常有帮助。
编辑 1
我想在显示“上一个”和“下一个”按钮的控件中放置一个隐藏字段。根据单击的按钮,我将使用 JavaScript 更新隐藏字段的值。现在的问题似乎是隐藏字段从未创建或与表单一起提交。我已经修改了控制器发布参数以接受附加字段,但它永远不会被提交,也不会在 FormCollection 中。
这是隐藏字段的代码。请注意,它是在育儿视图的表单内部调用的用户控件中生成的(希望这是有道理的)。
<% Html.Hidden("navDirection", navDirection); %>
想法?
编辑 2
我已经解决了所有这些问题。我最迟会在星期二详细发布代码。下面介绍的解决方案可能会被选为答案,因为这让我有了正确的思考过程。
简而言之,解决方案是使用一个类似于建议的导航类,并根据当前视图和所有视图的字符串列表确定下一页或上一页的逻辑。创建了一个局部视图/用户控件来显示上一个/下一个按钮。用户控件有 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 代码,但它的工作原理可以从所选答案和以下 sn-p 中推断出来,该 sn-p 根据当前视图和返回视图名称方向(上一个或下一个)。
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 类型。
另一个注意事项是 NavigationTracker 的 FirstPage 和 LastPage 属性是静态的,因此我实际上在 global.asax.cs 文件中使用 NavigationTracker.FirstPage 进行路由。这意味着我可以转到我的 NavigationTracker 类并在一个地方更改整个应用程序的流程。
我很乐意对此解决方案提出任何意见或批评。我承认这可能不是一个很好的解决方案,但乍一看,我很满意。
希望对你有帮助。
【问题讨论】:
标签: c# asp.net asp.net-mvc asp.net-mvc-2