查看和从第三方实体拉取说明的“一多列表”框

本文关键字:列表 一多列表 说明 第三方 实体 | 更新日期: 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
    }
}