0

DisplayFor と DisplayForModel を呼び出して、ビュー内のさまざまな要素タイプで IEnumerable<> を反復しようとしています。各要素/モデル タイプに対して定義されたテンプレートがあります。

私がしたいのは、ViewData.ModelMetadata.ContainerType をテンプレート内からチェックして、テンプレートがコレクションの一部として呼び出されたかどうかを判断できるようにすることです。

簡単な例:

Index1.aspx: Foos のコレクションをレンダリングします。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Foo>>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <ul><%:Html.DisplayForModel()%></ul>
</asp:Content>

Index2.aspx: Bar から Foo をレンダリングします。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Bar>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <%:Html.DisplayFor(m => m.Foo)%>
</asp:Content>

Shared\DisplayTemplates\Foo.ascx: Foo のコンテキスト対応テンプレート。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Foo>" %>
<%  var tag = typeof(IEnumerable).IsAssignableFrom(ViewData.ModelMetaData.ContainerType) ? "li" : "div";
%>    <<%:tag%>><%:Model.Name%></<%:tag%>>

この例の問題は、ViewData.ModelMetaData.ContainerType が、Index1.aspx で解決されたときにテンプレートで null になることです。Brad Wilson の投稿などで読んだことから、IEnumerable の使用とそれがインターフェイスであることが関係しています。

ContainerType が設定されていることを確認する方法はありますか? おそらく ModelMetadataProvider を作成することでしょうか? 私は簡単に調べましたが、ContainerType の値は以前に決定されてからプロバイダーに渡されたようです。

任意の提案をいただければ幸いです。

4

1 に答える 1

0

これは私が今取り組んだ機能的な解決策ですが、コレクションをモデル内のリストに変換する必要があり、テンプレートはコンテキストを認識しないため、制限があり問題があります。

Index1.aspx: Foos のコレクションをレンダリングします。

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IList<Foo>>" %>
<asp:Content ContentPlaceHolderID="MainPlaceHolder" runat="server">
    <%:Html.DisplayForModel("List")%>
</asp:Content>

Shared\DisplayTemplates\List.ascx: 特別なコレクション テンプレート。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IList>" %>
<ul class="list">
<%  for(int i = 0, count = Model.Count; i < count; i++)
    {
%>      <li><%:Html.DisplayFor(m => m[i])%></li>
<%  }
%>
</ul>

Shared\DisplayTemplates\Foo.ascx: コンテキストを認識しない Foo のテンプレート。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Foo>" %>
    <div><%:Model.Name%></div>

このシナリオは、以前に説明した方法と同様の方法で処理したいと思います。そのため、モデル テンプレートは、呼び出し元が名前で参照する特別なケースのテンプレートを作成する代わりに、出力をフォーマットする方法を自分で決定できます。

于 2010-06-17T22:03:02.650 に答える