2013-07-30 211 views
2

我有一個MVC應用程序,我試圖放在一起,需要一些選擇列表和下拉列表。MVC和實體框架選擇列表

所以,我有以下型號....

public class Task 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    ...... 
    public virtual ICollection<Monitor> Monitors { get; set; } 
    public virtual ICollection<Resource> Resources { get; set; } 

} 
public class Monitor 
{ 
    public int ID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public IList<Task> Tasks { get; set; } 
} 
    public class Resource 
{ 
    public int ID { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ..... 

    public IList<Task> Tasks { get; set; } 

有趣的是,當我顯示的任務列表中,顯示就好了其他性質,我需要顯示一個列表'監視器'和在下面顯示的索引視圖中分配給任務的'資源'列表。

@model IEnumerable<ResourceManager.Models.Task> 

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 

<p> 
    @Html.ActionLink("Create New", "Create") 
</p> 
<table> 
    <tr> 
     ..... 
     <th> 
      @Html.DisplayNameFor(model => model.Title) 
     </th> 
     ..... 
     <th> 
      @Html.DisplayNameFor(model => model.Monitors) 
     </th> 
     <th> 
      @Html.DisplayNameFor(model => model.Resources) 
     </th> 
     <th></th> 
    </tr> 

@foreach (var item in Model) { 
    <tr> 
     ..... 
     <td> 
      @Html.DisplayFor(modelItem => item.Title) 
     </td> 
     ..... 
     <td> 
      @if (item.Monitors == null || item.Monitors.Count == 0) 
       {<span>No Monitors Assigned</span>} 
      else 
       { string.Join(", ", item.Monitors.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName))); } 
     </td> 
     <td> 
      @Html.DisplayFor(modelItem => item.Resources) 
     </td> 
     <td> 
      @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | 
      @Html.ActionLink("Details", "Details", new { id=item.ID }) | 
      @Html.ActionLink("Delete", "Delete", new { id=item.ID }) 
     </td> 
    </tr> 
} 
</table> 

這裏是控制器....

public ActionResult Index() 
    { 
     var tasks = from t in db.Tasks where t.IsActive == true select t; 
     return View(tasks); 
    } 

我想爲監視器列表和資源列表中顯示爲對指數的字符串,刪除和詳細信息視圖,即'監視器1,監視器2,監視器3'和'資源1,資源2,資源3'。

但是在其他視圖(創建和編輯)中,我希望它們顯示爲可選列表。

+0

要存儲選定的監視器或選擇的資源在哪裏? – ataravati

+0

我有一個監視器,任務和資源的表,TaskMonitor和TaskResources的交叉鏈接表 –

回答

6

首先在你的控制器創建選擇列表,

 

    var monitors = //Your linq query 

    ViewData["ddlList"] = monitors .Select(x => new SelectListItem { 
     Text = x.FirstName, 
     Value = x.Id.ToString() 
    }).ToList(); 

然後你就可以在你的視圖按如下方式使用它,

<%=Html.DropDownList("myList") %> 
+0

我將嘗試這個列表。我會讓你知道它是如何工作的。 –

+0

好的,所以var allMonitors從數據庫返回所有的監視器,但是當它試圖創建ViewData時出現錯誤,說「LINQ to Entities無法識別方法'System.String ToString()'方法,並且這種方法不能轉換成商店表達式。「 –

4

對於監視/資源的顯示(因爲你想要它們顯示爲一個逗號分隔的列表),你可以使用string.Join

<td> 
    @string.Join(",", Model.Monitors.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName))) 
</td> 

爲了能夠實際使用Html.DisplayFor,您必須創建自定義顯示模板,以便Razor實際知道如何響應。爲此,請在您的Views文件夾中創建名爲「DisplayTemplates」的新文件夾,並在其中創建一個名爲「Monitors.cshtml」和「Resources.cshtml」的新分部視圖,分別強制鍵入IEnumerable<Monitor>IEnumerable<Resource>。然後,該文件裏面,你只需添加大致與上面相同的代碼:

@model IEnumerable<Monitor> 

@string.Join(",", Model.Select(m => string.Format("{0} {1}", m.FirstName, m.LastName))) 

然後在您看來,您可以撥打:

@Html.DisplayFor(m => m.Monitors, "Monitors") 

不幸的是,在這個例子中,你必須提供模板名稱是因爲列表DisplayFor的默認行爲是爲顯示模板多次渲染顯示模板,每次爲列表的每個成員提供一次。您可以做這樣的事情:

# Monitor.cshtml 

@model Monitor 

@Model.FirstName @Model.LastName, 

然後:

@Html.DisplayFor(m => m.Monitors) 

但你的最後一個項目必須在最後一個逗號。

要編輯列表,您只需將選擇列表傳遞給您的視圖。最理想的情況是,你可以使用視圖模型來做到這一點,但爲了簡單起見,我將在這裏使用ViewBag。在你的控制器動作:

ViewBag.MonitorChoices = db.Monitors.Select(m => new SelectListItem 
    { 
     Value = m.ID.ToString(), 
     Text = string.Format("{0} {1}", m.FirstName, m.LastName) 
    }); 

然後,在你創建/編輯觀點:

@Html.ListBoxFor(m => m.Monitors, ViewBag.MonitorChoices) 
+0

你的答案中的細節很好!乾杯。 – TheOptimusPrimus

+0

我要試試這個,讓你知道它是如何工作的。意想不到的迴應! –

+0

這對索引和詳細信息視圖非常有效。但是,我遇到了懶惰綁定的問題。即使它們在數據庫中,我的顯示器也會返回null。 –

0

嘗試如下,

 
var monitors = //Your linq query 

    List monitorList = new List(); 
    foreach (var monitor in monitors){ 
     SelectListItem item = new SelectListItem(); 
     item.Text = monitor.FirstName; 
     item.Value = monitor.Id.ToString(); 
     monitorList .Add(item); 
    } 


ViewData["ddlList"] = monitorList;