TheRedEye Ответов: 2

Как создать пользовательский элемент управления (user control) в MVC


В MVC, я изо всех сил сделать тот функционал, который я использовал, чтобы получить от ASP.net пользовательских элементов управления форм. Я хотел бы многоразовый кусок кода, который содержит кучу входных данных, но в конечном итоге вернет одно значение модели. Ради простого примера предположим,что у меня есть следующая модель представления.
public class Person 
{
   public string Name { get;set;}
   public DateTime DateOfBirth { get; set;}
   public DateTime DateOfDeath { get; set;}
}

Я хотел бы создать элементы управления вводом, которые составляют поля DateTime для повторного использования, поэтому я предполагаю, что помещу их в PartialView, _myDateControl. cshtml, следующим образом:
<!-- Don't know how to make the IDs unique every time i call this partialview on the same page -->
<label>Enter the year: <input type="text" name="year" /></label>
<label>Enter the month: <input type="text" name="month" /></label>
<label>Enter the day: <input type="text" name="day" /></label>

Затем вид что-то вроде
@model Person
@using (Html.BeginForm())
{
   @Html.EditorFor(m => m.Name)
   @Html.Partial("_MyDateControl") @*How do i map this to DateOfBirth *@
   @Html.Partial("_MyDateControl") @*How do i map this to DateOfDeath *@
   <input type="submit" value="Save Person" />
}


Правильно ли я поступаю? Или я должен смотреть на пользовательские HTML-помощники?

Что я уже пробовал:

Все примеры PartialViews, которые я вижу, просто имеют базовые html-теги, а не какие-либо входные теги, которые будут частью формы.

2 Ответов

Рейтинг:
12

TheRedEye

Большое спасибо, Брайан. Вы поставили меня на правильный путь с классом DummyControl. Мой реальный пользовательский элемент управления должен был иметь около 12 входов, поэтому иметь имя элемента управления для каждого было немного грязно. В конечном счете я искал свойство HtmlFieldPrefix для решения проблемы уникальных входных идентификаторов. Вот простой пример решения, которое я получил:

// data model
public class Person
{
    public string Name { get; set; }
    public DateTimeControl DateOfBirth { get; set; }
    public DateTimeControl DateOfDeath { get; set; }
}
// model to hold UserControl values
public class DateTimeControl
{
    [Display(Name = "Day: ")]
    public string Day { get; set; }
    [Display(Name = "Month: ")]
    public string Month { get; set; }
    [Display(Name = "Year: ")]
    public string Year { get; set; }
}


А частичный вид выглядит следующим образом:
@model Models.DateTimeControl
<div class="form-group">
    @Html.LabelFor(m => m.Day)
    @Html.EditorFor(m => m.Day, new { @class = "form-control" })
</div>
<div class="form-group">
    @Html.LabelFor(m => m.Month)
    @Html.EditorFor(m => m.Month, new { @class = "form-control" })
</div>
<div class="form-group">
    @Html.LabelFor(m => m.Year)
    @Html.EditorFor(m => m.Year, new { @class = "form-control" })
</div>

Затем я могу использовать частичное представление несколько раз в одном и том же представлении, преодолевая уникальные идентификаторы с помощью свойства HtmlFieldPrefix.
<div class="form-group">
  @Html.LabelFor(m => m.Name)
  @Html.EditorFor(m => m.Name, new { @class = "form-control" })
</div>
  @Html.Partial("_DateTimeInput", Model.DateOfBirth, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "DateOfBirth" } })
  @Html.Partial("_DateTimeInput", Model.DateOfDeath, new ViewDataDictionary { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "DateOfDeath" } })


Так что сгенерированный HTML-код:
                    <div class="form-group">
    <label for="DateOfBirth_Day">Day: </label>
    <input class="text-box single-line" id="DateOfBirth_Day" name="DateOfBirth.Day" type="text" value="" />
</div>
<div class="form-group">
    <label for="DateOfBirth_Month">Month: </label>
    <input class="text-box single-line" id="DateOfBirth_Month" name="DateOfBirth.Month" type="text" value="" />
</div>
<div class="form-group">
    <label for="DateOfBirth_Year">Year: </label>
    <input class="text-box single-line" id="DateOfBirth_Year" name="DateOfBirth.Year" type="text" value="" />
</div>

                    <div class="form-group">
    <label for="DateOfDeath_Day">Day: </label>
    <input class="text-box single-line" id="DateOfDeath_Day" name="DateOfDeath.Day" type="text" value="" />
</div>
<div class="form-group">
    <label for="DateOfDeath_Month">Month: </label>
    <input class="text-box single-line" id="DateOfDeath_Month" name="DateOfDeath.Month" type="text" value="" />
</div>
<div class="form-group">
    <label for="DateOfDeath_Year">Year: </label>
    <input class="text-box single-line" id="DateOfDeath_Year" name="DateOfDeath.Year" type="text" value="" />
</div>

При смешивании с дополнительными входными данными во внешнем виде вся модель заполняется и отправляется контроллеру, как и ожидалось, когда пользователь нажимает кнопку отправки.


Bryian Tan

Я рад, что ты все понял. Молодец!!!

Рейтинг:
1

Bryian Tan

Вот вам пример.

Модель: YourDummyModel - это объект/модель приложения, YourDummyControl-это имя/идентификатор и значение элемента управления

public class YourDummyModel
{
    public string FieldOne { get; set; }
    public string FieldTwo { get; set; }
}

public class YourDummyControl
{
    public string ControlName { get; set; }
    public string ControlValue { get; set; }
}


Контроллер : При загрузке страницы заполните модель некоторыми фиктивными данными. При обратной передаче приложение должно вернуть контроллеру значение в текстовом поле
public ActionResult TestPartialView()
{
    var model = new YourDummyModel();
    model.FieldOne = "Your Field 1";
    model.FieldTwo = "Your Field 2";

    return View(model);
}

[HttpPost]
[AllowAnonymous]
public ActionResult TestPartialView(YourDummyModel model)
{
    return View(model);
}


_MySharedView.cshtml по : Это общий вид / пользовательский элемент управления
@model WebApplication1.Models.YourDummyControl
<div class="form-group">
    @Html.Label(Model.ControlName, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBox(Model.ControlName , Model.ControlValue, new { @class = "form-control" })
    </div>
</div>


YourView : Это вид страницы, на самом деле ваша страница может иметь больше элементов. Страница вызовет метод Html. RenderPartial для загрузки частичного представления и передачи имени элемента управления и значения элемента управления из класса модели.
@model WebApplication1.Models.YourDummyModel
<h2>TestPartialView</h2>
@using (Html.BeginForm())
{
    Html.RenderPartial("~/Views/shared/_MySharedView.cshtml",
                new WebApplication1.Models.YourDummyControl { ControlName = "FieldOne", ControlValue = Model .FieldOne  });

    Html.RenderPartial("~/Views/shared/_MySharedView.cshtml",
               new WebApplication1.Models.YourDummyControl { ControlName = "FieldTwo", ControlValue = Model.FieldTwo  });
    <input type="submit" value="Create" class="btn btn-default" />
}


Более сложное управление:
ASP.NET управление слайд-шоу MVC3 с помощью jQuery и XML[^]

Больше читать:
Генерировать уникальные идентификаторы для элементов HTML в частичный вид внутри оператора foreach. | The ASP.NET форумы[^]

Надеюсь, это поможет. Если не спросите.


Karthik_Mahalingam

5

Bryian Tan

Спасибо, сэр!