2015-08-14 64 views
0

在ASP.NET Web窗体中,可以从母版页修改页面控件。例如,在页面“/ Sample”中,我可以通过执行以下操作将TextBox1设置为只读。什么是Find Control的MVC等价物?

//Site.master.cs 
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (Request.Path.ToUpper().Contains("/SAMPLE")) 
    { 
     TextBox TB = MainContent.FindControl("TextBox1") as TextBox; 
     TB.ReadOnly = true; 
    } 
} 

的问题是...... 是否有同等的方式在使用一个SiteLayout MVC应用程序做到这一点?

背景:我们已经购买了MVC应用程序并且有权修改 的源代码。我们需要定制一些页面上的行为。 只会被几十人使用,所以表现不会很明显。如果这是一个Web Forms 应用程序,我们将使用上述方法。 但是这个应用程序 是用MVC编写的,它让我们的web表单程序员(我)对如何最好地继续下去感到困惑。当我们不得不修补软件时,定制大量页面将会非常头疼。在一个中心位置 中进行所有更改将会更容易管理。你怎么能有一个地方,你可以在MVC中以编程方式定制其他页面?

回答

0

没有MVC相当于为FindControl,因为观点是建立在一个单一的操作,其中ASP.NET控件建立和修改在几个不同的事件。您无需查找控件,只需在构建时指定其所有属性即可。

大致相当于ASP.NET控件(至少在这种情况下)是HTML helper。 HTML助手实现为静态扩展方法,它允许在视图之间共享它们,并在加载视图时执行一些操作。

using System.Web.Mvc; 
using System.Web.Mvc.Html; 

public static class MyExtensions 
{ 
    public static MvcHtmlString TextBox1(this HtmlHelper helper, string name) 
    { 
     if (helper.ViewContext.HttpContext.Request.Path.ToUpper().Contains("/SAMPLE")) 
     { 
      return InputExtensions.TextBox(helper, name, null, new { @readonly = "readonly" }); 
     } 

     return InputExtensions.TextBox(helper, name); 
    } 
} 

使用

〜/查看/共享/ _Layout.cshtml

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8" /> 
     <title>@ViewBag.Title - My ASP.NET MVC Application</title> 
     <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> 
     <meta name="viewport" content="width=device-width" /> 
     @Styles.Render("~/Content/css") 
     @Scripts.Render("~/bundles/modernizr") 
    </head> 
    <body> 
     <header> 
      <div class="content-wrapper"> 
       <div class="float-left"> 
        <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p> 
       </div> 
       <div class="float-right"> 
        <section id="login"> 
         @Html.Partial("_LoginPartial") 
        </section> 
        <nav> 
         <ul id="menu"> 
          <li>@Html.ActionLink("Home", "Index", "Home")</li> 
          <li>@Html.ActionLink("About", "About", "Home")</li> 
          <li>@Html.ActionLink("Contact", "Contact", "Home")</li> 
         </ul> 
        </nav> 
       </div> 
      </div> 
     </header> 
     <div id="body"> 
      @RenderSection("featured", required: false) 
      <section class="content-wrapper main-content clear-fix"> 

       @* Render custom HTML Helper *@ 
       @Html.TextBox1("test") 

       @RenderBody() 
      </section> 
     </div> 
     <footer> 
      <div class="content-wrapper"> 
       <div class="float-left"> 
        <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p> 
       </div> 
      </div> 
     </footer> 

     @Scripts.Render("~/bundles/jquery") 
     @RenderSection("scripts", required: false) 
    </body> 
</html> 

注意的是,还可以直接把逻辑的观点,但你不能重用其他视图中的逻辑,它使你的视图看起来很混乱。

至于从文本框中读取数据,您需要将它放在<form>标签内,以便将其发布到控制器操作方法,这与提交按钮单击事件大致相当。与ASP.NET不同,MVC支持多个<form>标签,因此您不必在页面上混合用于不同操作的逻辑。

+0

有没有办法在渲染时添加一个函数“如果Page = X然后将Textbox1设置为ReadOnly”? –

+0

你可以使用[sections](http://weblogs.asp.net/scottgu/asp-net-mvc-3-layouts-and-sections-with-razor)来这样做。您只需要覆盖每个适用视图的部分(当page = X时)。但是你给出的例子是当URL包含'/ sample'时禁用文本框,所以这就是我提供的答案。 – NightOwl888

+0

该评论意味着不同的帖子。我马上删除它。你太棒了,不应该注意到它! –

0

您的问题非常广泛。但一般来说,如果您想根据某些条件在剃须刀视图中为您的控件提供只读渲染,则可以尝试下面的方法。

您应该为您的视图模型添加IsReadOnly属性,并使用该属性以您想要的方式呈现控件。

public class CreateCustomerVM 
{ 
    public bool IsReadOnly {set;get;} 

    //Other properties goes here 
    public string Email { set; get; } 
    public string Name { set; get; } 

} 

在您的Action方法中,根据您的条件设置IsReadOnly规格值。

public ActionResult Index() 
{ 
    var vm=new CreateCustomerVM(); 

    //Set the value based on your condition 
    vm.IsReadOnly=true; 

    return View(vm);  
} 

而且在您看来,您使用IsReadOnly属性,以确定是否要显示一个只读控。

@model YourNameSpaceGoesHere.CreateCustomerVM 
@using (Html.BeginForm()) 
{ 
    @Html.TextBoxFor(m => m.Email) 

    if(Model.IsReadOnly) 
    { 
     @Html.TextBoxFor(m => m.Name, new { @readonly = "readonly" }) 
    } 
    else 
    { 
     @Html.TextBoxFor(m => m.Name) 
    } 
    <input type="submit"/> 
} 
+0

是的,这并没有回答这个问题,因为我打算提出这个问题。这可能是我的错,没有足够好的解释。我想要一个中心位置,我可以重写MVC中的控制行为。我知道MVC是不同的,“控件”的想法与Web Forms更加一致。但是,我需要一个位置,我可以覆盖文本框/复选框/按钮/ etc ...属性。我知道这可能是一个奇怪的请求,但请记住,当商业MVC应用程序升级/打补丁时,我们需要一种易于管理的管理方式来管理更改。 –