MVC3 на основе бритвы htmlhelper с лямбда-выражениями полей на основе модели - PullRequest
3 голосов
/ 05 июня 2011

Я создаю свободный HtmlHelper в MVC - для создания сетки на основе HTML.Я знаю о mvc contrib и WebGrid - но я делаю свое собственное и у меня есть определенная проблема:

Я должен ввести это:

@Html.DSGridFor().AddColumn(x=>x.FirstOrDefault().Message)

, но я хочу иметь возможность печататьthis:

@Html.DSGridFor().AddColumn(x=>x.Message)

Код, который вызывается, когда я начинаю с @ Html.DSGridFor (), - берется в модели на основе страницы.

public static DSGridHelper<TModel> DSGridFor<TModel>(this HtmlHelper<TModel> html)
{
   return new DSGridHelper<TModel>(html);
}

, а затем в классе DSGridHelper Iесть это:

public DSGridHelper<TModel> AddColumn(Expression<Func<TModel, dynamic>> property, string HeaderText = null)
        {
            string ColumnName = (property.Body as MemberExpression).Member.Name;

            DSGridColumn DSGC = new DSGridColumn();
            DSGC.ColumnName = ColumnName;
            DSGC.HeaderText = HeaderText ?? ColumnName;
            DSColumnList.Add(DSGC);

            return this;
        }

public List<DSGridColumn> DSColumnList { get; set; }

и класс столбцов на данный момент действительно базовый:

  public class DSGridColumn
    {
        public DSGridColumn()
        {

        }

        public string ColumnName { get; set; }
        public string HeaderText { get; set; }

    }

Я могу заставить этот код работать нормально с именами столбцов на основе строк, но я хочу объявитькод на странице бритвы должен быть простым по формату и строго типизированным.На данный момент я должен набрать x => x.First (). Message, но мне действительно нужно только x => x.Message для идентификации столбца.

Я ценю любую помощь.

ОБНОВЛЕНИЕ

Благодаря Джастину я теперь могу предоставить мой / наш код.

Просмотр:

@(Html.DSGridFor3().AddColumn(x => x.Message)
                   .AddColumn(x => x.Host)
                   .ToMvcString())

HTML Helperвызов:

public static DSGridHelper3<T> DSGridFor3<T>(this HtmlHelper<IEnumerable<T>> htmlHelper)
{
         return new DSGridHelper3<T>(htmlHelper);
}

Возвращаемый класс:

public class DSGridHelper3<T>
    {
        private HtmlHelper _htmlHelper;
        //private IEnumerable<T> _dataList;
        public List<DSGridColumn> DSColumnList { get; set; }

        public DSGridHelper3(HtmlHelper<IEnumerable<T>> htmlHelper)
        {
            _htmlHelper = htmlHelper;
           // _dataList = htmlHelper.ViewData.Model;
            DSColumnList = new List<DSGridColumn>();
        }

        public DSGridHelper3<T> AddColumn(Expression<Func<T, object>> property)
        {
            string columnName = (property.Body as MemberExpression).Member.Name;
            DSGridColumn DSGC = new DSGridColumn();
            DSGC.ColumnName = columnName;
            DSGC.HeaderText = columnName;
            DSColumnList.Add(DSGC);

            return this;
        }

        public MvcHtmlString ToMvcString()
        {
            sb.Append("<table>");
            sb.Append("<tr>");
            sb.Append("<td>");
            sb.Append("hello world within a table");
            sb.Append(@"</td>");
            sb.Append("<td>");
            sb.Append("hello world within a table");
            sb.Append(@"</td>");
            sb.Append(@"</tr>");
            sb.Append(@"</table>");


            return new MvcHtmlString(sb.ToString());

        }
    }

ОБНОВЛЕНИЕ 2

Если вы хотите вручную вставить другой тип (возможно, потому что высобираемся получить небольшое количество табличных данных из ViewData, а не из модели страницы), а вот еще немного кода:

View:

@(Html.DSGridFor3<DanSoftware.MVC.Areas.Errors.Code.ELMAH_Error>().AddColumn(x => x.Message).ToMvcString();)

Альтернативная подпись для DSGridHelper...helper

public static DSGridHelper3<T> DSGridFor3<T>(this HtmlHelper htmlHelper)
        {
            return new DSGridHelper3<T>(htmlHelper);
        }

Дополнительный конструктор:

public DSGridHelper3(HtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
            // _dataList = htmlHelper.ViewData.Model;
            DSColumnList = new List<DSGridColumn>();
        }

Надеюсь, это кому-нибудь поможет и спасибо Джастину!

1 Ответ

2 голосов
/ 05 июня 2011

У меня нет Visual Studio, но я попробую ...

Я бы взял коллекцию как тип данных либо в вашем методе DsGridFor, либо в методе AddColumn. Это позволит вам отправлять строго типизированные аргументы из коллекции. Скажем, вы хотели использовать обобщенный метод AddColumn для данной коллекции с доступом к свойствам класса по сравнению с методами коллекции, это выглядело бы примерно так (просто пример):

    public static DSGridHelper<T> AddColumn<T>(this HtmlHelper<IEnumerable<T>> htmlHelper, Expression<Func<T, object>> property) where T : class
    {
        string columnName = (property.Body as MemberExpression).Member.Name;

        DSGridColumn DSGC = new DSGridColumn();
        DSGC.ColumnName = ColumnName;
        DSGC.HeaderText = HeaderText ?? ColumnName;
        DSColumnList.Add(DSGC);

        return this;
    }

В вашей ситуации, для нового класса DsGridHelper я мог бы сначала явно установить тип модели, а затем добавить перегрузки по мере того, как я иду:

    public static DSGridHelper<T> DSGridFor<T>(this HtmlHelper<IEnumerable<T>> htmlHelper) where T : class
    {
        return new DSGridHelper<T>(htmlHelper);
    }

И тогда мой DsGridHelper может выглядеть примерно так:

public class DsGridHelper<T>
{
    private HtmlHelper _htmlHelper;
    private IEnumerable<T> _dataList;

    public DsGridHelper(HtmlHelper<IEnumerable<T>> htmlHelper)
    {
        _htmlHelper = htmlHelper;
        _dataList = htmlHelper.ViewData.Model;
    }

    public DsGridHelper<T> AddColumn(Expression<Func<T, object>> property)
    {
        string columnName = (property.Body as MemberExpression).Member.Name;
        DSGridColumn DSGC = new DSGridColumn();
        DSGC.ColumnName = ColumnName;
        DSGC.HeaderText = HeaderText ?? ColumnName;
        DSColumnList.Add(DSGC);

        return this;
    }
}
...