Страницы

Поиск по вопросам

четверг, 18 октября 2018 г.

Столкнулся с проблемой, когда модель содержит много свойств. Как писать эффективнее?

Дело в том, что впервые столкнулся с моделью, где более 40 свойств, которые нужно отобразить.
[Display(Name = "Название 1")] public string Name1 { get; set; } [Display(Name = "Название 2")] public int Name2 { get; set; } [Display(Name = "Название 3")] public int Name3 { get; set; } [Display(Name = "Название 4")] public int Name4 { get; set; }
В представлении мне нужно отобразить данные в виде таблицы

@Html.LabelFor(c => common.Name1) @Html.LabelFor(c => common.Name2) @Html.LabelFor(c => common.Name3)

Мне кажется нелогичным такой способ вывода информации и подозреваю, что можно сделать это более легким способом, который пока не смог найти... Подскажите, пожалуйста.
Есть ли что-либо похожее на это
@{ foreach(var DisplayName in Model.ObjectPropertyAttributies) }
DisplayName


Ответ

Если по работе нужно создавать много однотипных файлов то можно в сторону кодогенерации посмотреть: https://msdn.microsoft.com/en-us/library/bb126445.aspx
Я это использую, чтобы делать заготовки под view model:
<#@ template debug="true" hostSpecific="false" #> <#@ output extension=".cs" #>
<#@ Assembly Name="System.Core" #> <#@ Assembly Name="$(SolutionDir)packages\Prism.Core.6.2.0\lib
et45\Prism.dll" #>
<#@ import namespace="System" #> <#@ import namespace="Prism.Mvvm" #> <# // This template generates the code for a ViewModel which is based on some model. // Also supposed that used MVVM pattern and Prism Library
// Full name of type for which will be generated ViewModel Type modelType = typeof(someType); PopulateTypeNameProperties(modelType);
// Namecpase inside which the code of ViemModel will be put string space = "Solution.ViewModel";
// Begining template's code #>namespace <#= space#> { // usings using <#= modelType.Namespace#>;
public class <#= modelType.Name #>ViewModel : BindableBase { #region Fields
<# foreach(var tuple in this.typeNameProperties) { #> private <#= tuple.Item1 #> <#= tuple.Item3 #>; <#}#>
#endregion
#region Property for binding
<# foreach(var tuple in this.typeNameProperties) { #> public <#= tuple.Item1 #> <#= tuple.Item2 #> { get { return this.<#= tuple.Item3 #>; }
set { this.SetProperty(ref this.<#= tuple.Item3 #>, value); } }
<#}#>
#endregion
public <#= modelType.Name #>ViewModel() {}
public <#= modelType.Name #>ViewModel(<#= modelType.Name #> model) { <# foreach(var tuple in this.typeNameProperties) { #> this.<#= tuple.Item3 #> = model.<#= tuple.Item2 #>; <#}#>}
public void UpdateViewModel(<#= modelType.Name #> model) { <# foreach(var tuple in this.typeNameProperties) { #> this.<#= tuple.Item2 #> = model.<#= tuple.Item2 #>; <#}#>}
public static explicit operator <#= modelType.Name #> (<#= modelType.Name #>ViewModel viewModel) { <# int beforeLast = typeNameProperties.Count - 1; #> return new <#= modelType.Name #> { <# for (int i = 0; i < beforeLast; ++i) { #> <#= typeNameProperties[i].Item2 #> = viewModel.<#= typeNameProperties[i].Item3 #>, <#}#><# if (typeNameProperties.Count > 1) { this.Write(string.Format("\t\t{0} = viewModel.{1}", typeNameProperties[beforeLast].Item2, typeNameProperties[beforeLast].Item3)); } this.Write("
"); #> }; } } } <# // Ending template's code #> <#+ // The storage for couple type - name of Properties private List> typeNameProperties = new List>();
private void PopulateTypeNameProperties(Type modelType) { foreach (var p in modelType.GetProperties()) { if (string.CompareOrdinal(p.Name, "ErrorMessage") == 0) { continue; }
string type = GetShortTypeName(p.PropertyType.Name);
var name = p.Name; char firstLetter = name[0]; var property = char.ToUpperInvariant(firstLetter).ToString() + name.Substring(1); var field = char.ToLowerInvariant(firstLetter).ToString() + name.Substring(1);
typeNameProperties.Add(new Tuple(type, property, field)); } } #>
<#+ private string GetShortTypeName(string typeName) { switch(typeName) { case "Int32": return "int";
/ .......
case "Object": return "object";
default: return typeName; } }
#>
Правда есть немного заморочек с отступами, и выглядит не очень читабельно. Но не нужно тратить время на медитативный набор свойств view model. Результат вот такой:
namespace Solution.ViewModel { // usings
public class CurrencyInfoViewModel : BindableBase { #region Fields
private string name; private string shortName; private DateTime modifyTime; private int id;
#endregion
#region Property for binding
public string Name { get { return this.name; }
set { this.SetProperty(ref this.name, value); } }
public string ShortName { get { return this.shortName; }
set { this.SetProperty(ref this.shortName, value); } }
public DateTime ModifyTime { get { return this.modifyTime; }
set { this.SetProperty(ref this.modifyTime, value); } }
public int Id { get { return this.id; }
set { this.SetProperty(ref this.id, value); } }
#endregion
public CurrencyInfoViewModel() {}
public CurrencyInfoViewModel(CurrencyInfo model) { this.name = model.Name; this.shortName = model.ShortName; this.modifyTime = model.ModifyTime; this.id = model.Id; }
public void UpdateViewModel(CurrencyInfo model) { this.Name = model.Name; this.ShortName = model.ShortName; this.ModifyTime = model.ModifyTime; this.Id = model.Id; }
public static explicit operator CurrencyInfo (CurrencyInfoViewModel viewModel) { return new CurrencyInfo { Name = viewModel.name, ShortName = viewModel.shortName, ModifyTime = viewModel.modifyTime, Id = viewModel.id }; } } }

Комментариев нет:

Отправить комментарий