我一直在使用 DelimitedStringHelper 扩展将项目序列转换为带有IEnumerable<T>
. 默认情况下,对序列中的每个项目调用 ToString() 以使用默认分隔符“,”来制定结果。
这具有以下效果:
public enum Days
{
[Display(Name = "Monday")]
Monday,
//Left out other days for brevity
[Display(Name = "Saturday")]
Saturday
}
并且,结合模型的其余部分:
[Mandatory(ErrorMessage = "Please select at least one day")]
[Display(Name = "What are the best days to contact you (select one or more days)?")]
[ContactClientDaySelector(BulkSelectionThreshold = 6)]
public List<string> ContactClientDayCheckBox { get; set; }
连同`[ContactClientDaySelector] 的代码:
public class ContactClientDaySelectorAttribute : SelectorAttribute
{
public override IEnumerable<SelectListItem> GetItems()
{
return Selector.GetItemsFromEnum<ContactClientDay>();
}
}
通过在视图中调用,将显示一个带有“星期一,...,星期六”的复选框列表:
@Html.FullFieldEditor(m => m.QuotePartRecord.ContactClientDayCheckBox)
注意:FullFieldEditor
是一个特殊的助手,它遍历enum
并使用BulkSelectionThreshold
将选择单选按钮列表、下拉列表、复选框列表或多选列表——在这种情况下,“6”将触发复选框列表的创建,因为我enum
有一个收集 6 个项目(即天)。
我的控制器只检查模型状态的有效性并传递到确认视图:
public ActionResult WrapUp(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("ExpenseInformation");
else if ((nextButton != null) && ModelState.IsValid)
return RedirectToAction("Confirm");
else
return View(quoteData);
}
public ActionResult Confirm(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("WrapUp");
else if ((nextButton != null) && ModelState.IsValid)
{
var quoteConfirm = _quoteService.CreateQuote(quoteData.QuotePartRecord);
return RedirectToAction("Submitted");
}
else
return View(quoteData);
}
现在,为了发布用户选择的复选框,我在确认视图页面中使用了以下内容:
[ContactClientDaySelector]
[ReadOnly(true)]
public List<string> ContactClientDayCheckBoxPost
{
get { return ContactClientDayCheckBox; }
}
这与 DelimitedStringHelper 结合将显示选择。例如,如果用户同时选择了星期一和星期二,则帖子将显示“星期一,星期二”。
但是,我不得不稍微更改我的代码,并int
专门用于复选框(长话短说:使用 NHibernate 会因为使用 而产生转换错误List<string>
,这是解决该问题的一种方法)。
我不得不删除enum
并用这个类替换它:
public class ContactClientDay
{
public int Id { get; set; }
public string Name { get; set; }
}
然后我修改了我的 Selector 类:
public class ContactClientDaySelectorAttribute : SelectorAttribute
{
public ContactClientDaySelectorAttribute()
{
//For checkboxes, number must equal amount of items
BulkSelectionThreshold = 6;
}
public override IEnumerable<SelectListItem> GetItems()
{
var contactClientDay = new List<ContactClientDay>
{
new ContactClientDay {Id = 1, Name = "Monday"},
//Left out other days for brevity
new ContactClientDay {Id = 6, Name = "Saturday"},
};
return contactClientDay.ToSelectList(m => m.Id, m => m.Name);
}
}
我将模型更改为:
public virtual int? ContactClientDayCheckBox { get; set; }
我将我的帖子更改为:
[ReadOnly(true)]
public string ContactClientDayCheckBoxPost
{
get { return QuotePartRecord.ContactClientDayCheckBox.ToString(); }
}
如果我这样做public int? ContactClientDayCheckBoxPost
,则确认页面上不会显示任何内容。
如果我改为使用public string ContactClientDayCheckBoxPost
然后做ContactClientDayCheckBox.ToString()
,它只会显示选择的第一个值的“名称”(仅“星期一”,而不是“星期一,星期二”)。
我无法弄清楚如何int
在这种情况下以编程方式转换序列(可能带有扩展名)?有什么想法/例子吗?提前致谢。
作为参考,这是DelimitedStringHelper
我正在使用的扩展:
public static class DelimitedStringHelper
{
public static string DefaultDelimiter = ", ";
/// <summary>
/// Convert a sequence of items to a delimited string. By default, ToString() will be called on each item in the sequence to formulate the result. The default delimiter of ', ' will be used
/// </summary>
public static string ToDelimitedString<T>(this IEnumerable<T> source)
{
return source.ToDelimitedString(x => x.ToString(), DefaultDelimiter);
}
/// <summary>
/// Convert a sequence of items to a delimited string. By default, ToString() will be called on each item in the sequence to formulate the result
/// </summary>
/// <param name="delimiter">The delimiter to separate each item with</param>
public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter)
{
return source.ToDelimitedString(x => x.ToString(), delimiter);
}
/// <summary>
/// Convert a sequence of items to a delimited string. The default delimiter of ', ' will be used
/// </summary>
/// <param name="selector">A lambda expression to select a string property of <typeparamref name="T"/></param>
public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> selector)
{
return source.ToDelimitedString(selector, DefaultDelimiter);
}
/// <summary>
/// Convert a sequence of items to a delimited string.
/// </summary>
/// <param name="selector">A lambda expression to select a string property of <typeparamref name="T"/></param>
/// <param name="delimiter">The delimiter to separate each item with</param>
public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> selector, string delimiter)
{
if (source == null)
return string.Empty;
if (selector == null)
throw new ArgumentNullException("selector", "Must provide a valid property selector");
if (string.IsNullOrEmpty(delimiter))
delimiter = DefaultDelimiter;
return string.Join(delimiter, source.Select(selector).ToArray());
}
}