How can I reuse a DropDownList in several views with .NET MVC

后端 未结 13 1049
感动是毒
感动是毒 2020-12-13 15:53

Several views from my project have the same dropdownlist...

So, in the ViewModel from that view I have :

public IEnumerable Fo         


        
相关标签:
13条回答
  • 2020-12-13 16:14

    I'd say that's fine to be honest, as it's only a repeat of a few lines of code. If it's really bothering you though, you could have all your controllers inherit from a BaseController (if they don't already) and store a method in there to get them all, something like:

    public IEnumerable<SelectListItem> GetFoos()
    {
        return fooRepository.GetAll().ToSelectList(x => x.Id, x => x.Name);
    }
    

    Then in your controllers you could do:

    var MyVM = new MyVM() {
        FooDdl = GetFoos()
    }
    
    0 讨论(0)
  • 2020-12-13 16:15

    If you really don't want to duplicate the code, place the code from the controllers into a helper class, and render the dropdown within a shared view (like _Layout.cshtml) that you'd then have to implement into your views by RenderPartial.

    Create a partial view, _MyDropdownView.cstml, which uses the helper class you threw the code from the controllers in with something like the following:

    @using MyNamespace.MyHelperClass
    <div id="myDropdown">@Html.DropDownListFor(model => model.Prop, MyVM as SelectList, "--Select a Property--")</div>
    

    Then, within your views:

    @Html.RenderPartial("_MyDropdownView")
    
    0 讨论(0)
  • 2020-12-13 16:17

    We also use a static class :

    public static class SelectLists
    {
            public static IList<SelectListItem> CompanyClasses(int? selected)
            {
                var session = DependencyResolver.Current.GetService<ISession>();
    
                var list = new List<SelectListItem>
                               {
                                   new SelectListItem
                                       {
                                           Selected = !selected.HasValue,
                                           Text = String.Empty
                                       }
                               };
    
                list.AddRange(session.All<CompanyClass>()
                                  .ToList()
                                  .OrderBy(x => x.GetNameForCurrentCulture())
                                  .Select(x => new SelectListItem
                                                   {
                                                       Selected = x.Id == (selected.HasValue ? selected.Value : -1),
                                                       Text = x.GetNameForCurrentCulture(),
                                                       Value = x.Id.ToString()
                                                   })
                                  .ToList());
    
                return list;
            }
    }
    

    In the view we have nothing special :

    @Html.DropDownListFor(x => x, SelectLists.CompanyClasses(Model))
    

    And sometime we also create an EditorTemplate so it's faster to reuse like this

    Model :

    [Required, UIHint("CompanyClassPicker")]
    public int? ClassId { get; set; }
    

    EditorTemplate :

    @model int?
    
    @if (ViewBag.ReadOnly != null && ViewBag.ReadOnly)
    {
        var item = SelectLists.CompanyClasses(Model).FirstOrDefault(x => x.Selected);
    
        if (item != null)
        {
            <span>@item.Text</span>
        }
    }
    else
    {
        @Html.DropDownListFor(x => x, SelectLists.CompanyClasses(Model))    
    }
    
    0 讨论(0)
  • 2020-12-13 16:20

    Create object with getter for your dropdown values:

    public static class DropDowns
    {
        public static List<SelectListItem> Items { 
           get
           {
               //Return values
           } 
        } 
    }
    

    Create Razor partial:

    @Html.DropDownListFor(m => "ChoosenItem", DropDowns.Items, "")
    

    Call partial:

    @Html.RenderPartial("DropDownItems")
    

    And finally receive ChoosenItem value in controller. Simply.

    0 讨论(0)
  • 2020-12-13 16:20

    I like to use static classes often in a helper class that I can call from any view.

    @Html.DropDownListFor(x => x.Field, PathToController.GetDropDown())
    

    and then in your controller have a method built like this

    public static List<SelectListItem> GetDropDown()
        {
            List<SelectListItem> ls = new List<SelectListItem>();
            lm = (call database);
            foreach (var temp in lm)
            {
                ls.Add(new SelectListItem() { Text = temp.name, Value = temp.id });
            }
            return ls;
        }
    

    Hopefully it helps.

    0 讨论(0)
  • 2020-12-13 16:24

    Extension methods to the rescue

    public interface ISelectFoo {    
        IEnumerable<SelectListItem> FooDdl { get; set; }
    }
    
    public class FooModel:ISelectFoo {  /* implementation */ }     
    
    public static void PopulateFoo(this ISelectFoo data, FooRepository repo)
    {
        data.FooDdl = repo.GetAll().ToSelectList(x => x.Id, x => x.Name);
    }
    
    
    //controller
    var model=new ViewModel(); 
    model.PopulateFoo(repo);
    
    
     //a wild idea
    public static T CreateModel<T>(this FooRepository repo) where T:ISelectFoo,new()
    {
        var model=new T();
        model.FooDdl=repo.GetAll().ToSelectList(x => x.Id, x => x.Name);
        return model;
     }
    
    //controller
     var model=fooRepository.Create<MyFooModel>();
    
    0 讨论(0)
提交回复
热议问题