I have a method which accepts one viewmodel. i have to replicate same method for different viewmodel. i tried something like functionname (t model) but it didnt work.I am new to generics.
Can some one help me
private void SetUpUserTypeDropDown(RegisterViewModel model)
{
var usertypes = GetuserTypes();
model.UserTypes = new List<SelectListItem> { };
usertypes.ForEach(t => model.UserTypes.Add(new SelectListItem() { Text = t.Text, Value = t.Value }));
}
private void SetUpUserforBackOfficeTypeDropDown(BackOfficeViewModel model)
{
var usertypes = GetuserTypes();
model.UserTypes = new List<SelectListItem> { };
usertypes.ForEach(t => model.UserTypes.Add(new SelectListItem() { Text = t.Text, Value = t.Value }));
}
private void SetUpProfileTypeDropDown(MyProfileViewModel model)
{
var usertypes = GetuserTypes();
model.UserTypes = new List<SelectListItem> { };
usertypes.ForEach(t => model.UserTypes.Add(new SelectListItem() { Text = t.Text, Value = t.Value }));
}
I am forced to copy paste same code with different method names. Can i get some help in this regard how to make a generic method which have input view model as generic input
Since all your *ViewModel-classes have a property named UserTypes of type List<SelectListItem> you can think about creating a base class for all *ViewModels:
public class ViewModelBase
{
public List<SelectListItem> UserTypes { get; set; }
// ... further code?
}
and inherit your view models from that class, for example:
public class RegisterViewModel : ViewModelBase
{
// implement specific behaviour
}
Then your method does not need to be generic, but can simply take a ViewModelBase as parameter:
private void SetUpUserType(ViewModelBase model)
{
var usertypes = GetuserTypes();
model.UserTypes = new List<SelectListItem> { };
usertypes.ForEach(t => model.UserTypes.Add(new SelectListItem() { Text = t.Text, Value = t.Value }));
}
Just for completeness, you can make this method generic:
private void SetUpUserType<T>(T model) where T : ViewModelBase
{
var usertypes = GetuserTypes();
model.UserTypes = new List<SelectListItem> { };
usertypes.ForEach(t => model.UserTypes.Add(new SelectListItem() { Text = t.Text, Value = t.Value }));
}
and use the constraint (where T : ViewModelBase) to make sure it's a type derived from ViewModelBase supporting that UserTypes property.
Related
I have two DbSets:
public DbSet<Reports.Models.Application> Application { get; set; }
public DbSet<Reports.Models.Category> Category { get; set; }
In the controller, I'm creating two List<SelectListItem>s:
var applications = _context.Application
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
var categories = _context.Category
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
I'd like to refactor this into a single, private method:
private List<SelectListItem> SelectList<T>(bool blankListItem = false)
{
var selectListItems = _context.<T> <------ doesn't compile
.Select(listItem => new SelectListItem
{
Value = listItem.ID,
Text = listItem.Name
}
).ToList();
if (blankListItem)
selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {{T.ToString}}", Value = "" }));
return selectListItems;
}
And call it twice:
var applications = SelectList<Application>();
var categories = SelectList<Category>();
or
var applications = SelectList<Application>(true); // add "choose"
var categories = SelectList<Category>(true); // add "choose"
What's the right way to define the _context.<T> part? Perhaps this should be an extension method of the DbSet instead?
Maybe you can have your dbsets inherit a base class. which would be representing the generic type T.
Something like;
public class BaseClassForDbSets
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Application : BaseClassForDbSets
{
}
public class Category : BaseClassForDbSets
{
}
and then your private method;
private IEnumerable<SelectListItem> GetSelectList<T>(IEnumerable<T> dataSource, bool blankListItem = false) where T : BaseClassForDbSets
{
var selectListItems = dataSource
.Select(listItem => new SelectListItem
{
Value = listItem.Id.ToString(),
Text = listItem.Name
}
).ToList();
if (blankListItem)
selectListItems.Insert(0, (new SelectListItem { Text = $"Choose {nameof(T)}", Value = "" }));
return selectListItems;
}
Then you would call it like;
var applicationCollection = GetSelectList(_context.Application);
var categoryCollection = GetSelectList(_context.Category);
Do note - not tested
My solution uses a different approach, but same result.
Start with an interface:
public interface IBaseSelectItem
{
int Id { get; set; }
string Name { get; set; }
}
Have your entities (Application and Category) implement the interface:
public partial class Category : IBaseSelectItem
{
public int Id { get; set; }
public string Name { get; set; }
}
Create an extension on DbSet:
public static IList<SelectListItem> AsSelectList<T>(this DbSet<T> dbSet, bool useChooseValueOption) where T : class, IBaseSelectItem
{
var selectList = dbSet
.Select(c => new SelectListItem { Value = c.Id.ToString(), Text = c.Name })
.ToList();
if (useChooseValueOption)
selectList.Insert(0, new SelectListItem { Value = "0", Text = "-Choose Value-" });
return selectList;
}
Then use like this:
var categoriesSelectList = _dbContext.Categories.AsSelectList();
How can i implement simple DropDownList without Id.
public AddItemModel()
{
Types = new SelectList(new []{"Type1", "Type2", "Type3"});
}
public SelectList Types { get; set; }
#Html.DropDownListFor(x => x.AddItem, ???
You will need a property on your view model to hold the selected value and then you may try this:
public AddItemModel()
{
var data = new [] { "Type1", "Type2", "Type3" };
Types = data.Select(x => new SelectListItem
{
Value = x,
Text = x,
});
}
public IEnumerable<SelectListItem> Types { get; set; }
public string SelectedType { get; set; }
and then in your view:
#Html.DropDownListFor(x => x.SelectedType, Model.Types)
This is my enum
public class Woodshape
{
public enum eWoodShape
{
Round = 10,
Oval = 20,
Plain = 30
}
}
Now i want to add this as a dropdownlist in my controller
public ActionResult Create()
{
List<string> li = new List<string>();
FieldInfo[] myEnumFields = typeof(Woodshape.eWoodShape).GetFields();
foreach (FieldInfo myField in myEnumFields)
{
if (!myField.IsSpecialName && myField.Name.ToLower() != "notset")
{
int myValue = (int)myField.GetValue(0);
li.Add(myField.Name);
}
}
ViewBag.ddlEnumshape = new SelectList(myEnumFields, "myValue", "Name");
return View();
}
and In my view binded it as..
<div>
#Html.DropDownList("ddlEnumshape", "-Select shape-")
/<div>
but, it is showing error
System.Reflection.RtFieldInfo' does not contain a property with the name 'myValue'.
Could anyone help me
public static IEnumerable<SelectListItem> GetListEnumWrap<TEnum>()
{
var items = new List<SelectListItem>();
if (typeof(TEnum).IsEnum)
{
foreach (var value in Enum.GetValues(typeof(TEnum)).Cast<int>())
{
var name = Enum.GetName(typeof(TEnum), value);
name = string.Format("{0}", name);
items.Add(new SelectListItem() { Value = value.ToString(), Text = name });
}
}
return items;
}
use:
#Html.DropDownListFor(m => m.Type, EnumExtensions.GetListEnumWrap<Types>())
I use this method:
public static Dictionary<int, string> EnumToDictionary<T>()
{
return Enum.GetValues(typeof (T)).Cast<T>().ToDictionary(x => Convert.ToInt32(x), x => x.ToString());
}
ViewBag.ddlEnumshape = new SelectList(EnumToDictionary<Woodshape.eWoodShape>, "Key", "Value");
I have got this controller:
public class NewPostController : Controller
{
List<SelectListItem> languages= new List<SelectListItem>();
public ActionResult Index()
{
ViewData["languages"] = new SelectList(languages, "Text", "Value", 1);
return View();
}
private void GetCountryList()
{
CultureInfo[] cultureList = CultureInfo.GetCultures(CultureTypes.AllCultures);
foreach (CultureInfo culture in cultureList)
{
languages.Add(new SelectListItem
{
Text = culture.DisplayName,
Value = culture.DisplayName,
});
}
}
}
The list of items should be established by their languages and be passed to the view.
#Html.DropDownList("languages",null,
"** Please Select **",
new { #class = "my-select-css-class" })
Nothing gets populated..Why?
GetCountryList()
You never call it.
Having a hard time getting this dropDownList to Bind. This is simply a list of states. The Model.State is "TX", but my dropdownlist is showing "AK", which is the first value in the list. Any thoughts?
<%: Html.DropDownListFor(
model => model.State,
new SelectList(
muniSynd.getStatecodesDropDown(),
"Value",
"Text",
Model.State.ToString().Trim()
)
)
%>
In my muniSynd class, which is a wrapper of my dataContext.....
public IList<StateCodeViewModel> getStatecodesDropDown()
{
var states = from p in this._MuniDc.Statecodes
select new StateCodeViewModel
{
Value = p.Statecode1.ToString().Trim(),
Text = p.Statecode1.ToString().Trim()
};
return states.ToList();
}
public class StateCodeViewModel
{
public string Value{get;set;}
public string Text{get;set;}
}
Im using LinqToSQL, here is the object
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Statecodes")]
public partial class Statecode
{
private string _Statecode1;
public Statecode()
{
}
[global::System.Data.Linq.Mapping.ColumnAttribute(Name="Statecode", Storage="_Statecode1", DbType="NVarChar(3)")]
public string Statecode1
{
get
{
return this._Statecode1;
}
set
{
if ((this._Statecode1 != value))
{
this._Statecode1 = value;
}
}
}
}
I've tried to replicate your problem, but my example below works fine:
public class HomeController : Controller
{
public ActionResult Index()
{
var viewModel = new IndexViewModel();
viewModel.State = "TX";
return this.View(viewModel);
}
public static IList<StateCodeViewModel> getStatecodesDropDown()
{
var stateCodes = new List<string> { "AX", "GH", "TX" };
var states = from p in stateCodes
select new StateCodeViewModel
{
Value = p,
Text = p
};
return states.ToList();
}
}
public class IndexViewModel
{
public string State { get; set; }
}
public class StateCodeViewModel
{
public string Value { get; set; }
public string Text { get; set; }
}
View
#using MVCWorkbench.Controllers
#model IndexViewModel
#{
ViewBag.Title = "title";
}
#Html.DropDownListFor(model => model.State,
new SelectList(HomeController.getStatecodesDropDown(),
"Value",
"Text",
Model.State.ToString().Trim()
)
)
Not sure what to suggest other then check that the State value is in the dropdown list. Also this could be a case-sensitivity issue perhaps?