Универсальное частичное представление: как установить универсальный класс как модель?

Раньше я получал обычные Swing Exception без отслеживаемой трассировки стека. Это потому, что я нарушал правила параллелизма в Swing. Этот SO ответ развивает: SwingWorker ProgressBar . По сути, убедитесь, что весь ваш код Swing вызывается в потоке рассылки событий.

12
задан Thomas Stock 21 May 2009 в 12:47
поделиться

4 ответа

Так сделать нельзя. Причина в том, что .aspx сгенерирует класс, над которым у вас нет особого контроля, и вы не можете добавить к нему общий параметр. Думаю, самый простой способ - передать его как объект .

5
ответ дан 2 December 2019 в 21:24
поделиться

You could make all your model types that you would pass into this partial inherit from a base class/interface that establishes the basic behavior that would be used by this partial view and accept any object of that class/interface type, or just have the view accept any type of object and then use reflection to base your partial view behavior off of.

EXAMPLE:

public interface IDisplayModel
{
    string DisplayText{get;set;}
    string ImageUrl{get;set;}
    string AltText{get;set;}
}

public interface ITrustGrid<T> where T : IDisplayModel
{    
    IPagedList<T> Elements { get; set; }    
    IList<IColumn<T>> Columns { get; set; }    
    IList<string> Headers { get; }
}

<%@ Control Language="C#" 
    Inherits="System.Web.Mvc.ViewUserControl<ITrustGrid<IDisplayModel>>" %>

Naturally, your IDisplayModel would vary based on your desired behavior. This would then allow you to pass in anything to this partial that implements this base interface to establish general behavior.

7
ответ дан 2 December 2019 в 21:24
поделиться

I agree with Mehrdad, as far as I know it isn't possible to make generic views. In one of my projects, I used an interface much like your one, and then passed delegate functions to the view that handle the specific rendering of each item.

For instance, I would have used a non-generic view data class with an additional field:

public interface ITrustGrid {
    IPagedList Elements { get; set; }
    IList<IColumn> Columns { get; set; }
    IList<string> Headers { get; }

    Func<object, string> ElementRenderer { get; }
}

In your main view you'll prepare the view data:

<%
ITrustGrid data = (ITrustGrid)ViewData["employeeGrid"];
data.ElementRenderer = new Func<object, string>(delegate(o) {
    var employee = (Employee)o;
    //render employee
    return html;
});

Html.RenderPartial("SimpleTrustGridViewer", data);
%>

While in your grid partial you'll process the grid as usual, and then call the delegate to render each single cell:

<%
foreach(var element in ViewData.Elements){
    %>
    <tr>
        <td><%=ViewData.ElementRenderer(element) %></td>
    </tr>
    <%
}
%>

Of course, the code above only renders a single cell for each element, you'll have to create a slightly more complex delegate to render multiple columns (or pass in an array of delegates, one for each column).

I think this would be one of the cleanest ways to do it, albeit a bit cumbersome.

1
ответ дан 2 December 2019 в 21:24
поделиться

@ Lck:

Я делаю что-то подобное в своем контроллере:

var columns = new List<IColumn<EmployeeInfoDTO>>
                  {
                      new Column<EmployeeInfoDTO>("Full name", e => string.Format("{0} {1}", e.FirstName, e.Name)),
                      new Column<EmployeeInfoDTO>("Examination date", e => e.ExaminationDate.HasValue? string.Format("{0} days ago", currentDate.Subtract(e.ExaminationDate.Value).Days) : "Unknown")
                  };

var employeeGrid = new TrustGrid<EmployeeInfoDTO> { Columns = columns, Elements = GetEmployees(currentPageIndex)};

ViewData["employeeGrid"] = employeeGrid;

Итак, в моем частичном представлении я могу сделать это:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ITrustGrid<EmployeeInfoDTO>>" %>
<table>
    <thead>
        <tr>
            <%
                foreach (string header in Model.Headers)
                    Response.Write(Html.Th(header));
            %>
        </tr>
    </thead>
    <tbody>
        <%
            foreach (var element in Model.Elements)
            {
                Response.Write("<tr>");
                foreach (var column in Model.Columns)
                    Response.Write(Html.Td(column.ValueExpression(element)));
                Response.Write("</tr>");
            }
        %>
    </tbody>
</table>
<div class="pager">
    <%= Html.Pager(Model.Elements.PageSize, Model.Elements.PageNumber, Model.Elements.TotalItemCount)%>
</div>

Как видите, нет кода в моем партиале зависит от используемого типа. Так что я все еще думаю, что есть простое решение.

0
ответ дан 2 December 2019 в 21:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: