如何在MVC中创建自定义控件(用户控件) [英] How to create custom control (user control) in MVC

查看:136
本文介绍了如何在MVC中创建自定义控件(用户控件)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MVC中,我很难获得我曾经从ASP.net webforms usercontrol获得的功能。我想要一个包含大量输入的可重用代码块,但最终会将单个值返回给模型。为了一个简单的例子,我假设我有以下视图模型。

  public   class  Person 
{
public string 姓名{获取; 设置;}
public DateTime DateOfBirth { get ; set ;}
public DateTime DateOfDeath { get ; set ;}
}



我想创建组成的输入控件DateTime字段是可重用的,所以我想我把它们放在PartialView,_myDateControl.cshtml中,如下所示:

 < ;! -    每次在同一页面上调用此部分视图时,不知道如何使ID唯一   - >   
< 标签 > 输入年份:< input type = text 名称 = / > < / label >
< label > 输入月份:< 输入 类型 = text name = month / > < / label >
< label > 输入日期:< 输入 类型 = text name = day / > < / label >



然后查看类似

 @ model的内容Person 
@using(Html.BeginForm())
{
@ Html.EditorFor(m => m.Name)
@ Html.Partial(_ MyDateControl)@ *如何将此映射到DateOfBirth * @
@ Html.Partial(_ MyDateControl)@ *如何将此映射到DateOfDeath * @
< 输入 type = submit value = 保存人员 / > ;
}





我是否以正确的方式解决这个问题?或者我应该看看自定义的Html助手吗?



我尝试过:



我看到的PartialViews的所有示例,似乎都有基本的html标签,而不是任何将成为表单一部分的输入标签。

解决方案

这里是一个例子。



模型:YourDummyModel是应用程序对象/模型,YourDummyControl是保存控件名称/ id和值

  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 = 你的领域1;
model.FieldTwo = 你的领域2;

return 查看(模型);
}

[HttpPost]
[AllowAnonymous]
public ActionResult TestPartialView(YourDummyModel model)
{
return 查看(模型);
}





_MySharedView.cshtml :这是共享视图/用户控件

 @ model WebApplication1.Models.YourDummyControl 
< div class = form-group >
@ Html.Label(Model.ControlName,new {@ class =col-md-2 control-label})
< div < span class =code-attribute> class = col-md-10 >
@ Html.TextBox(Model.ControlName,Model.ControlValue,new {@ class =form-control})
< / div >
< / div >





YourView :这是页面视图,实际上,您的网页可能包含更多元素。该页面将调用Html.RenderPartial方法来加载局部视图并从Model类传入控件名称和控件值。

 @ 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});
< 输入 < span class =code-attribute> type = submit value = 创建 class = btn btn-default / >
}





更复杂的控制:

ASP.NET MVC3幻灯片控件使用jQuery和XML [ ^ ]



更多阅读:

生成用于部分视图的Html元素的唯一ID在foreach语句中调用。 | ASP.NET论坛 [ ^ ]



希望这个帮助。如果没有问。


非常感谢Brian。你用DummyControl类把我放在了正确的轨道上。我的真实世界用户控件需要有大约12个输入,因此每个控件的名称都有点混乱。最终我在寻找HtmlFieldPrefix属性来解决唯一的输入ID问题。以下是我最终得到的简单示例解决方案:



  //  数据模型 
public class Person
{
public string 名称{获得; set ; }
public DateTimeControl DateOfBirth { get ; set ; }
public DateTimeControl DateOfDeath { get ; set ; }
}
// 用于保存UserControl值的模型
< span class =code-keyword> public
class DateTimeControl
{
[Display(Name = 日:)]
public 字符串日{获取; set ; }
[显示(名称= 月:)]
public string 月{ get ; set ; }
[显示(名称= 年份:)]
public string 年{获取; 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.Ed itorFor(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属性克服唯一ID。

 <   div      =  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 = DateOfBirth_Day > 日:< / label >
< input class = 文本框单行 id = DateOfBirth_Day 名称 = DateOfBirth.Day type = text = / >
< / div >
< div class = form-group >
< label for = DateOfBirth_Month > 月份:< / label >
< 输入 class = 文本框单行 id = DateOfBirth_Month name = DateOfBirth.Month type = text value = / < span class =code-keyword>>
< / div >
< div class = form-group >
< label = DateOfBirth_Year > 年份:< / label >
< input = 文本框单行 id = DateOfBirth_Year 名称 = DateOfBirth.Year type = text value = / >
< / div >

< div < span class =code-attribute> class = form-group >
< label < span class =code-attribute> for = DateOfDeath_Day > 日:< / label >
< 输入 c lass = text-box single-line id = DateOfDeath_Day name = DateOfDeath.Day type = text = / >
< / div >
< div class = form-group >
< label for = DateOfDeath_Month > 月:< / label >
< 输入 class = 文本框单行 i d = DateOfDeath_Month 名称 = DateOfDeath.Month type = text value = / >
< / div >
< div class = < span class =code-keyword> form-group >
< label for = DateOfDeath_Year > 年份:< / label >
< span class =code-keyword>< input class = text-box single-line id = DateOfDeath_Year name = DateOfDeath.Year type = text value = / >
< / div >



当与外部视图中的其他输入混合使用时,整个模型将被填充并在用户点击提交按钮时按预期发送给控制器。 / BLOCKQUOTE>

In MVC, I'm struggling get the functionality that I used to get from a ASP.net webforms usercontrol. I'd like a reusable chunk of code that contains a bunch of inputs but will ultimately return a single value to the model. For the sake of a simple example lets say i have the following viewmodel.

public class Person 
{
   public string Name { get;set;}
   public DateTime DateOfBirth { get; set;}
   public DateTime DateOfDeath { get; set;}
}


I'd like to create the input controls that make up the DateTime fields to be reusable, so I guess I put them in a PartialView, _myDateControl.cshtml, as follows:

<!-- 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>


Then a view something like

@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" />
}



Am I going about this the right way? Or should I be looking at custom Html Helpers?

What I have tried:

All the examples of PartialViews I see, just seem to have basic html tags and not any input tags that will be part of a form.

解决方案

Here is an example.

Model: YourDummyModel is the application Object/Model, YourDummyControl is to hold the control name/id and value

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; }
}



Controller : On page load, populate the Model with some dummy data. On Postback, the application should return the value in the Textbox to the controller

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 : This is the shared view/ user control

@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 : This is the page view, in reality, your page might have more elements. The page will call the Html.RenderPartial method to load the partial view and passing in the control name and control value from the Model class.

@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" />
}



More complicated control:
ASP.NET MVC3 Slideshow Control using jQuery and XML[^]

More reading:
Generate unique ids for Html Elements of partial view called inside foreach statement. | The ASP.NET Forums[^]

Hope this help. If not ask.


Thank you very much Brian. You put me on the right track with the DummyControl class. My real world user control needed to have about 12 inputs on it, so having a control name for each was a bit messy. Ultimately I was looking for the HtmlFieldPrefix property to solve the unique input IDs problem. Here's the simple example solution I ended up with:

// 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; }
}



And the partial view as follows:

@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>


Then I can use the partial view multiple times in the same view, overcoming the unique IDs with the HtmlFieldPrefix property.

<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" } })



So that the generated HTML is:

                    <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>


When mixed with additional inputs in the outer View, the entire model is populated and sent to the controller as expected when the user hits the submit button.


这篇关于如何在MVC中创建自定义控件(用户控件)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆