我设法弄清楚了一些事情。尽管我的问题与您的问题不完全相同,但它肯定可以帮助您。但首先要做的事情。
问题
我有许多控件(在我的情况下它们是部分视图)。例如:
Views/Shared/EditName.cshtml
Views/Shared/EditAddress.cshtml
Views/Shared/EditEmail.cshtml
Views/Shared/EditFavoriteColour.cshtml
我想定义这些控件的组(在数据库或 web.config 中),例如:
SimpleEditGroup:
EditName
ExtendedEditGroup:
EditName
EditEmail
FullEditGroup:
EditName
EditAddress
EditEmail
EditFavoriteColour
然后我想基于特定组渲染视图。我在想下面的语法就足够了。
@Html.Partial("ControlGroup:ExtendedEditGroup", Model)
解决方案草案
我想创建自己的渲染引擎,它将执行以下操作:
- 如果视图的名称以“ControlGroup:”开头,则使用先前定义的组来呈现页面。每个控件都应由 RazorViewEngine 呈现。
- 如果视图的名称不以“ControlGroup:”开头,则让 RazorViewEngine 完成它的工作。
研究
我找到了以下资源:
- CodeProject 上的文章 - ASP.NET MVC3 中的自定义 ViewEngine
- 基于 StackOverflow 问题的文章 - Creating a Widget system in ASP.NET MVC 3
- 我向您推荐这本书Pro ASP.NET MVC 3 Framework。它将让您了解可以在 ASP.NET MVC 3 中自定义多少东西
- 当然,ASP.NET MVC 3 RTM的源代码非常有帮助。
最终解决方案
我的视图引擎:
public class MyViewEngine : RazorViewEngine
{
IDictionary<string, List<string>> groups = new Dictionary<string, List<string>>();
public MyViewEngine()
{
// Temporary data source
groups["SimpleEditGroup"] = new List<string>() { "EditName"};
groups["ExtendedEditGroup"] = new List<string>() { "EditName", "EditEmail"};
}
public override ViewEngineResult FindView(ControllerContext controllerContext,
string viewName, string masterName, bool useCache)
{
if (viewName.StartsWith("ControlGroup"))
{
var groupName = viewName.Split(':')[1];
var controls = new List<ViewEngineResult>();
foreach (var controlName in groups[groupName])
{
// Find each control using Razor magic
var control = base.FindPartialView(controllerContext, controlName, useCache);
if (control.View != null)
{
controls.Add(control);
}
}
if(controls.Count > 0)
return new ViewEngineResult(new MyView(controls), this);
}
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
我的视图.cs:
public class MyView : IView
{
IList<ViewEngineResult> controls;
public MyView(IList<ViewEngineResult> _controls)
{
controls = _controls;
}
public void Render(ViewContext viewContext, TextWriter textWriter)
{
// For simplicity I used table for layout
textWriter.Write("<table border='1'>");
foreach (var ctrl in controls)
{
textWriter.Write("<tr><td>");
// Render control using Razor
ctrl.View.Render(viewContext, textWriter);
textWriter.Write("</td></tr>");
}
textWriter.Write("</table>");
}
}
不要忘记在 Global.asax 中注册您的新引擎ViewEngines.Engines.Add(new MyViewEngine());
美好的结局
Render.Partial
我可以通过两种方式使用它:使用或仅从PartialView
我的控制器返回嵌入到视图中。
让我知道它是否对您有帮助。您还可以分享您的解决方案。