我設法弄清楚了一些事情。雖然我的問題並不完全一樣,但它確實可以幫助你。但首先是事情。
問題
我有很多的控制(在我的情況下,他們是局部視圖)。例如:
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 - Custom ViewEngine in ASP.NET MVC3
- 基於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是非常有用的。
最終解決
MyViewEngine:
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);
}
}
MyView.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
嵌入視圖。
讓我知道它是否對你有幫助。而且你也可以分享你的解決方案。
好問題。其實我有非常類似的問題。有關這方面的消息嗎? –
我從來沒有找到一個理想的解決方案,所以我使用ASPX視圖引擎的頁面只包含部分剃刀視圖。不漂亮,但它的作品。而且我仍然使用剃刀爲我的大多數標記 – Cleggy