Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以专门为IEnumerable属性创建HtmlHelper吗?_C#_Ienumerable_Html Helper - Fatal编程技术网

C# 我可以专门为IEnumerable属性创建HtmlHelper吗?

C# 我可以专门为IEnumerable属性创建HtmlHelper吗?,c#,ienumerable,html-helper,C#,Ienumerable,Html Helper,我想创建一个可以在IEnumerable属性上使用的HtmlHelper 目的是这样使用它: @Html.DisplayForEnumerable(m => m.EnumerableItemsProperty, "ViewTemplateName"); 如果可能的话,我想使用m=>m.Itemslambda语法(而不是通过Model.Items) 这是我迄今为止最大的努力。但是我不确定如何从expression参数中获取items变量 我怀疑我可能必须使用类似于IEnumerable的东

我想创建一个可以在IEnumerable属性上使用的HtmlHelper

目的是这样使用它:

@Html.DisplayForEnumerable(m => m.EnumerableItemsProperty, "ViewTemplateName");
如果可能的话,我想使用
m=>m.Items
lambda语法(而不是通过
Model.Items

这是我迄今为止最大的努力。但是我不确定如何从expression参数中获取
items
变量

我怀疑我可能必须使用类似于
IEnumerable
的东西作为表达式的返回类型,但我对泛型非常陌生,不知道如何实现它

public static MvcHtmlString DisplayForEnumerable<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, IEnumerable>> expression, string templateName, object additonalViewData = null)
{
    var sb = new StringBuilder();

    // how to get items variable?

    foreach (var item in items)
    {
        var item1 = item;
        sb.Append(html.DisplayFor(m => item1, templateName, additonalViewData));
    }

    return MvcHtmlString.Create(sb.ToString());
}
public static MvcHtmlString DisplayForEnumerable(此HtmlHelper html、表达式、字符串模板名、对象additonalViewData=null)
{
var sb=新的StringBuilder();
//如何获取项目变量?
foreach(项目中的var项目)
{
var item1=项目;
sb.Append(html.DisplayFor(m=>item1,templateName,additonalViewData));
}
返回MvcHtmlString.Create(sb.ToString());
}
更新

澄清一下——我之所以采用这种方法,是因为我希望能够为同一个模型指定不同的模板。如果指定特定模板,则不会出现正常的
DisplayFor()
枚举


我知道我可以手动枚举,但我宁愿使用这种方法,除非有更通晓此道的人另有建议。

您需要帮助

public static MvcHtmlString DisplayForEnumerable<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string templateName, object additionalViewData = null)
{
    ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
    IEnumerable collection = metaData.Model as IEnumerable;
    if (collection == null)
    {
        return helper.DisplayFor(expression, templateName, additionalViewData );
    }
    StringBuilder html = new StringBuilder();
    foreach (var item in collection)
    {
        html.Append(helper.DisplayFor(m => item, templateName, additionalViewData).ToString());
    }
    return MvcHtmlString.Create(html.ToString());
}
您还可以为每个控制器创建特定的显示和编辑器模板,例如
/Views/yourControllerName/DisplayTemplates/Person.cshtml
。这允许您在
/Persons/Index
中使用一个模板,在
/organization/Details/1
中使用另一个模板,该模板可能会显示与
组织相关的
Persons
列表


最后,如果您确实需要在同一控制器中为
Person
创建两个不同的模板,那么您可以使用视图模型,例如
class PersonVM
class AssociatedPersonVM
,并为每个
MVC已经具有该模板的对象创建一个
EditorTemplate
。它只是
@Html.DisplayFor(m=>m.EnumerableItemsProperty)
,您可以为集合中使用的类型创建一个
EditorTemplate
。谢谢Stephen。如果可能,我希望能够使用各种模板,并且如果指定特定模板,则不会发生自动枚举。我知道我可以手动枚举,但我喜欢这样做。你不建议这样做吗?不知道你的意思。如果您有一个模型,比如说
Person.cs
,那么您将创建一个
EditorTemplate
-
/View/Shared/EditorTemplates/Person.cshtml
,然后
DisplayFor()
方法将为集合中的每个
Person
生成正确的html。如果希望不同的模板与不同的控制器关联,则可以将它们放在
/Views/yourControllerName/EditorTemplates
文件夹中。我的意思是,我希望能够为同一个模型指定不同的模板。例如“AsPanel”、“AsListGroupItem”等。我想如果你使用视图模型(比如
Person.cs
AssociatedPerson.cs
并为每个视图模型创建一个
EditorTemplate
),你会发现这要容易得多。但是如果你真的想这样做,我可以添加一个答案。这是一个模型答案,大量的信息——非常感谢。
@Html.DisplayFor(m => m.yourCollectionProperty)