在asp.net中的下拉列表中显示特定的枚举值.净Mvc
本文关键字:枚举 Mvc 显示 asp net 下拉列表 | 更新日期: 2023-09-27 18:15:02
我有一个Enum Class
和4个statuses
,分别是Created
, Dispatched
, Delivered
和Delayed
。
目前,这四个都出现在我的Edit Delivery page
的dropdown
中。
我想要的是,如果我的status
是Created
那么我应该ONLY能够将其更改为Dispatched
,如果我的status
是Dispatched
我应该ONLY能够将其更改为Delivered
或Delayed
,如果我的status
是Delayed
我应该ONLY能够将其更改为Dispatched
或Delivered
。
这些都应该发生在我的Edit Delivery page
上。您还会注意到,我不希望Created
出现在上面的任何一个列表中,因为我只需要Create Delivery
。
所以,基本上我想要实现的是当我的delivery status
被设置为Created
时,我应该只在我的Enum下拉列表中看到分派,当我希望编辑该交付时。类似地,对于分派,如果我的状态被设置为分派,那么我只想看到Delivered
或Delayed
。同样的Delayed
,我只想看到Dispatched
和Delivered
。
我对MVC相当陌生,如果有人能提出一个解决方案,我将非常感激!
请让我知道是否需要任何额外的代码,我会把它添加到问题。
Enum类:public enum Status
{
Created, Dispatched, Delivered, Delayed
}
交付视图模型:
public class DeliveryVM
{
public int? ID { get; set; }
public Status Status { get; set; }
}
Delivery Edit View:
<div class="form-group">
@Html.LabelFor(model => model.Status, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EnumDropDownListFor(model => model.Status, htmlAttributes: new { @class = "form-control", @id="dropdown" })
@Html.ValidationMessageFor(model => model.Status, "", new { @class = "text-danger" })
</div>
</div>
您必须使用自定义选择列表而不是使用EnumDropDownListFor()
helper方法。
首先定义一个获取下一个集合列表的策略。请参阅下面的StrategicStatesExtension
类,它可以提供您所定义的各自的状态列表。类正在定义扩展方法,以便您可以以流畅的样式使用该方法。注意:保持当前状态在下一个可能的状态中显示在表单中作为默认选择项。
public static class StrategicStatesExtension
{
public static Status[] Created
{
get
{
return new [] { Status.Created, Status.Dispatched };
}
}
public static Status[] Dispatched
{
get
{
return new [] { Status.Delayed, Status.Delivered, Status.Dispatched };
}
}
public static Status[] Delayed
{
get
{
return new [] { Status.Delivered, Status.Dispatched, Status.Delayed };
}
}
public static Status[] GetAssociatedValidStatus(this Status currentStatus)
{
switch (currentStatus)
{
case Status.Created:
return Created;
case Status.Dispatched:
return Dispatched;
case Status.Delayed:
return Delayed;
case Status.Delivered:
return Status.Delivered;
default:
throw new ArgumentOutOfRangeException("Invalid current state received.");
}
}
public static List<SelectListItem> ToDropDownList(this Status[] sourceStates)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in sourceStates)
{
items.Add(
new SelectListItem {
Value = item.ToString("d"), // Value of enum (short)
Text = item.ToString() // Name of enum
});
}
return items;
}
这个策略扩展方法的用法如下:
public class DeliveryVM
{
public int? ID { get; set; }
public Status Status { get; set; }
public List<SelectListItem> States { get; set; }
public DeliveryVM()
{
// Sample usage: only for demo you need to call this in other method
// e.g. where your model is being filled with data.
this.States = Status.GetAssociatedValidStatus().ToDropDownList();
}
}
最后,而不是使用@Html.EnumDropDownListFor
,你需要从ViewData或ModelProperty建立新的属性状态列表
@Html.DropDownListFor("Statuses",
(List<SelectListItem>)ViewData["Statuses"],"value", "text", htmlAttributes: new { @class = "form-control", @id="dropdown" })
From Model属性:
@Html.DropDownListFor("Statuses",
(model.Statuses,"value", "text", htmlAttributes: new { @class = "form-control", @id="dropdown" })
EnumDropDownListFor()
方法将为枚举中的每个项生成选项。相反,您需要使用' DropDownListFor()方法。
为SelectList
的视图模型添加一个额外的属性
public class DeliveryVM
{
public int? ID { get; set; }
[Required(ErrorMessage = "Please select the status")]
public Status Status { get; set; }
public SelectList StatusList { get; set; } // add this
}
然后在GET方法中,基于现有的Status
构建所需的选项。注意,您只需要构建一个表示枚举值的string
列表,因为当您发布时,DefautModelBinder
会将发布的string
值转换为相应的enum
值。
Delivery delivery = // get your data model
DeliveryVM model = new DeliveryVM
{
ID = ... // set other properties based on data model
};
// Build list of options basd on current status
List<string> options = new List<string>();
if (delivery.Status == HealthHabitat.Models.Status.Created)
{
model.Status = HealthHabitat.ViewModels.Status.Dispatched; // its the only choice so set as the default selection
options.Add(HealthHabitat.ViewModels.Status.Dispatched.ToString());
}
else if (delivery.Status == HealthHabitat.Models.Status.Dispatched)
{
options.Add(HealthHabitat.ViewModels.Status.Delivered.ToString());
options.Add(HealthHabitat.ViewModels.Status.Delayed.ToString());
}
else if (delivery.Status == HealthHabitat.Models.Status.Delayed)
{
options.Add(HealthHabitat.ViewModels.Status.Dispatched.ToString());
options.Add(HealthHabitat.ViewModels.Status.Delivered.ToString());
}
model.StatusList = new SelectList(options);
return View(model);
在视图
@Html.LabelFor(m => m.Status, new { @class = "control-label col-md-2" })
@Html.DropDownListFor(m => m.Status, Model.StatusList, "Please select", new { @class = "form-control" }) // unclear why you are changing the id attribute?
@Html.ValidationMessageFor(m => m.Status, new { @class = "text-danger" })
在POST方法中,选择的值将被正确地绑定到视图模型的Status
属性
旁注:不清楚你做什么,当当前状态是Delivered
(也许不呈现任何控件?),如果当前状态是Created
,你只允许一个选择(Dispatched
),所以似乎没有必要在这种情况下也呈现一个控件。