查看和从第三方实体拉取说明的“一多列表”框
本文关键字:列表 一多列表 说明 第三方 实体 | 更新日期: 2023-09-27 18:35:32
我的背景是C#.Net Win Forms,我目前正在学习使用EF 6.1和MVC 5构建Web应用程序。我在一个培训网站上看了几个关于MVC,html,jquery的视频,谷歌是我的朋友,通常是。但是,我已经搜索并搜索了这个答案,但没有找到我需要的确切内容。
我正在使用EF形式的数据库优先方法,对于这个问题,我有三个表。
Event {int Id, datetime CreatedDate, varchar(50) Description}
EventType {int EventId, int TypeEventId}
TypeEvent {int Id, varchar(50) Description}
我在事件和事件类型上有一个 1-多关系,在类型事件到事件类型上有一个 1-多关系。
我想创建一个视图,允许我在单个页面上创建事件。由于一个事件可以有多个类型,我希望它们在多选框中。我用过
@Html.ListBoxFor(m => m.EventType ...)
但是我无法使描述正常工作。目前,我正在使用基架将从 EF 创建的所有默认控制器。我想我可能需要制作自己的控制器或为下拉框创建部分视图。
处理这种情况的最佳方法是什么?
编辑
我已经能够启动我的 1-多列表框并使用多选。但是,我在将模型数据传递到我的后期操作时遇到了一个小问题。
型
public class EventViewModel
{
//This is my primary Entity
public Event Event { get; set; }
//Properties for ListBox
public IEnumerable<int> selectedTypeEventId;
public IEnumerable<TypeEvent> TypeEvent { get; set; }
}
控制器
public ActionResult Create()
{
EventViewModel m = new EventViewModel();
List<TypeEvent> listTypeEvent = db.TypeEvents.ToList();
m.TypeEvent = listTypeEvent;
return View(m);
}
// POST: Event/Create
[HttpPost]
public ActionResult Create(EventViewModel m, IEnumerable<int> selectedTypeEventId)
{
if (ModelState.IsValid)
{
List<EventType> listEventType = new List<EventType>();
db.Events.Add(m.Event);
db.SaveChanges();
foreach (int i in selectedTypeEventId)
{
EventType et = new EventType();
et.EventId = m.Event.Id;
et.TypeEventId = i;
db.EventTypes.Add(et);
}
db.SaveChanges();
}
return View("Index");
}
视图
@model TMS.Models.EventViewModel
@{
ViewBag.Title = "Create";
}
@using (Html.BeginForm())
{
<div class="form-horizontal">
<h4>Event</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.Event.Description, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(m => m.Event.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(m => m.Event.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.Label("Event Types", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.ListBoxFor(m => m.selectedTypeEventId, new SelectList(Model.TypeEvent, "Id", "Description"), new { @id = "TypeEvent", @multiple = "multiple", @class = "form-control", @name = "TypeList" })
</div>
</div>
}
//This turns ListBox into DropDownCheckBoxList
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).ready(function () {
$('#TypeEvent').multiselect();
});
</script>
}
当我发布此表单时,我必须向控制器添加一个 IEnumerable 才能从列表框中获取数据。所有其他数据通过
@Html.EditFor
如何将列表框所选数据添加到模型信息中,而不必在发布操作时传递额外的参数?
编辑我只想说这是漫长的新年,我只是忽略了代码。在我的模型中,我改变了
public IEnumerable<int> selectedTypeEventId;
自
public IEnumerable<int> selectedTypeEventId { get; set; }
有助于获取/设置属性。
尝试使用以下视图模型并从控制器填充 TypeEvents
public class EventViewModel
{
public int Id {get;set;}
public string Description {get;set;}
public int TypeEventId
public IEnumerable<TypeEvent> TypeEvents {get;set;}
}
public class YourController
{
[HttpGet]
public ActionResult CreateEvent()
{
var viewModel = new EventViewModel();
viewModel.TypeEvents = ... // fill Data for DropDownList here
return View(viewModel);
}
[HttpPost]
public ActionResult CreateEvent(EventViewModel viewModel)
{
// You should have all the data you need in the viewModel
}
}
然后在视图中:
@Html.DropDownListFor(m => m.TypeEventId, new SelectList(Model.TypeEvents,"Id","Description") )
控制器的 POST 操作应执行数据库/业务逻辑调用
如果您希望能够一次添加多个类型事件,则必须以不同的方式执行此操作...例如,使用字典创建一个存储库,其中 GUID 作为键,并将此 Guid 添加到视图模型中。再创建 2 个控制器发布操作,一个用于添加新的事件类型,另一个用于删除它。显示附加了哪些 EventType 的部分应该放在部分视图中,该视图填充了 2 个操作并重新发送到客户端。我最近不得不这样做,它看起来像这样:
@model Apps4KidsWeb.Models.AddAppViewModel
@using Apps4KidsWeb.Domain
<table>
@foreach (KeyValuePair<int, int> item in Model.OperatingSystems)
{
<tr>
<td>@operatingSystems[item.Value]</td>
<td>
@Ajax.ActionLink(
"Remove",
"RemoveOperatingSystem",
"Admin",
new { guid = Model.Guid, id = item.Key },
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "operatingSystems"
})</td>
</tr>
}
</table>
和包含视图:
@model Apps4KidsWeb.Models.AddAppViewModel
@{
ViewBag.Title = "Add App";
ViewBag.CurrentPage = "Add App";
}
<div class="float">
<h3>Categories</h3>
<div id="categories">
@Html.Partial("_Categories", Model)
</div>
@using (Ajax.BeginForm("AddCategory", "Admin",
new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "categories", InsertionMode = InsertionMode.Replace }))
{
@Html.HiddenFor(model => model.Guid)
@Html.EditorFor(model => model.Category)
<input type="submit" value="Add" />
}
</div>
<div class="float">
<h3>Operating Systems</h3>
<div id="operatingSystems">
@Html.Partial("_OperatingSystems", Model)
</div>
@using (Ajax.BeginForm("AddOperatingSystem", "Admin",
new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "operatingSystems", InsertionMode = InsertionMode.Replace }))
{
@Html.HiddenFor(model => model.Guid)
@Html.EditorFor(model => model.OS)
<input type="submit" value="Add" />
}
</div>
<div class="clear"></div>
@using (Html.BeginForm("AddApp", "Admin"))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Guid)
@Html.EditorForModel()
<p>
<input type="submit" value="Weiter" />
</p>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
控制器:
/// <summary>
/// Adds an operating system to the AddAppViewModel
/// </summary>
/// <param name="Guid">The Guid of the item</param>
/// <param name="OS">The id of the operating system</param>
/// <returns>PartialView _OperatingSystems</returns>
[HttpPost]
public ActionResult AddOperatingSystem(string Guid, int OS)
{
var viewmodel = EditedAppRepository.GetInstance().GetApp(Guid);
viewmodel.AddOperatingSystem(OS);
return PartialView("_OperatingSystems", viewmodel);
}
/// <summary>
/// Removes an operating sytem from the AddAppViewModel
/// </summary>
/// <param name="Guid">The Guid of the item</param>
/// <param name="id">The id of the operating system</param>
/// <returns></returns>
[HttpPost]
public ActionResult RemoveOperatingSystem(string Guid, int id)
{
var viewmodel = EditedAppRepository.GetInstance().GetApp(Guid);
viewmodel.RemoveOperatingSystem(id);
return PartialView("_OperatingSystems", viewmodel);
}
和存储库:
using Apps4KidsWeb.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Apps4KidsWeb.Models
{
public class EditedAppRepository
{
#region singleton
private static EditedAppRepository singleton;
public static EditedAppRepository GetInstance()
{
if (singleton == null)
{
singleton = new EditedAppRepository();
}
return singleton;
}
private EditedAppRepository()
{
this.repository = new Dictionary<string, AddAppViewModel>();
}
#endregion
#region fields
private Dictionary<string, AddAppViewModel> repository;
#endregion
#region methods
public AddAppViewModel CreateNewApp(IApp app)
{
string guid = Guid.NewGuid().ToString();
AddAppViewModel result = new AddAppViewModel(app) { Guid = guid };
repository.Add(guid, result);
result.Saved += OnAppSaved;
return result;
}
public AddAppViewModel CreateNewApp(IRecommendationEx recommendation)
{
string guid = Guid.NewGuid().ToString();
AddAppViewModel result = new AddAppViewModel(recommendation) { Guid = guid };
repository.Add(guid, result);
result.Saved += OnAppSaved;
return result;
}
public AddAppViewModel CreateNewApp()
{
string guid = Guid.NewGuid().ToString();
AddAppViewModel result = new AddAppViewModel() { Guid=guid };
repository.Add(guid, result);
result.Saved += OnAppSaved;
return result;
}
public AddAppViewModel GetApp(string guid)
{
if (guid != null && repository.ContainsKey(guid))
{
return repository[guid];
}
return null;
}
private void OnAppSaved(object sender, EventArgs e)
{
AddAppViewModel model = (AddAppViewModel)sender;
repository.Remove(model.Guid);
}
public byte[] GetAppPicture(string guid, int id)
{
return repository[guid].Images[id];
}
#endregion
}
}