2012-01-05 3 views
0

私のビューで編集アドレスを実装しようとしています。MVC 3のドロップダウンボックス

住所には、通りや町などの基本的な文字列があります。国名もあります。私は国のデータベースにテーブルを持っています。私のコントローラで

は、私はこれらの国のためにSelectListのを作成します。

ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id }); 

は今、私の見解で、私は、ユーザーが国を選択できるようにするには、この選択リストを使用できるようにしたいです。

私が当初考えていた:私は国を選択してを示している必要がありビューを表示するときに

public class Company() 
{ 
    public Address HeadOffice { get; set; } 
    public Address SecondOffice { get; set; } 
} 

@Html.DropDownList("countryId", (IEnumerable<Country>)ViewBag.Countries, "Select") 

は、私は2つのアドレスを持っています。私はこのようなものを選択した場合ので、私は私のコントローラでこれを行うことができるとは思わない:これはHeadOfficeのために動作します

ViewBag.Countries = _countryRepo.GetAll().Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == model.HeadOffice.Id ? true : false }); 

ここから2つのオプションがあります。 2つの異なる選択リストを作成するか、ビュー内で選択リストを手動で作成します。

<select name="HeadOffice.CountryId"> 
    @foreach(var c in (IEnumerable<Country>)ViewBag.Countries) 
    { 
     <option value="@c.Id" @(c.Id == Model.HeadOffice.Id ? "selected='true'" : "">@c.Name</option> 
    } 
</select> 

どのような方法が最適ですか?どちらも間違っていて、うまくないようです。この問題にアプローチするにはよりよい方法がありますか?

答えて

2

私はかつて、その後2つの異なるリストを公開する国のリストを取り込みビューモデルを使用します。

public class MyViewModel 
{ 
    public Address HeadOffice { get; set; } 
    public Address SecondOffice { get; set; } 

    public IEnumerable<Country> Countries { get;set;} 

    public IEnumerable<SelectListItem> HeadOfficeCountries 
    { 
    get 
    { 
     return GetCountriesList(Countries, HeadOffice.Id); 
    } 
    } 

    public IEnumerable<SelectListItem> SecondOfficeCountries 
    { 
    get 
    { 
     return GetCountriesList(Countries, SecondOffice.Id); 
    } 
    } 

    private IEnumerable<SelectListItem> GetCountriesList(IEnumerable<Country> countries, int forAddress) 
    { 
    return countries.Select(c => new SelectListItem { Text = c.Name, Value = c.Id, Selected = c.Id == forAddress ? true : false }); 
    } 
} 
+0

優秀!素晴らしいアイデア - 私はこれをやるしかありません。ありがとう。 – Terry

+0

@Terry great !!私は助けてうれしいです。 –

+0

@BassamMehanniここで同じコードを2回書いています。 ASP.NET MVCのプリンシパルの1つは、DRYアプローチに従うことです。 – tugberk

1

は、次のブログ記事を見てください:

A Way of Working with Html Select Element (AKA DropDownList) In ASP.NET MVC

あなたはブログの記事内のすべての詳細を見つけるでしょう。

編集:あなたのケースのために

は、以下のコードは正常に動作する必要があります:

public ActionResult Index() { 

    ViewBag.DLForHeadOffice = GetItems(model.HeadOffice.Id); 
    ViewBag.DLForSecondOffice = GetItems(model.SecondOffice.Id); 

    //continue your code 
} 


private IEnumerable<SelectListItem> GetItems(int id) { 

    _countryRepo.GetAll(). 
     Select(c => 
      new SelectListItem { 
       Text = c.Name, 
       Value = c.Id, 
       Selected = c.Id == id ? true : false 
      } 
     );  
} 
+0

私はそれが意図されていたとは思っていませんが、ブログの投稿リンクがありません。 –

+0

@FrazellThomas今それがあります。 – tugberk

+0

ありがとうございますが、私はすでにドロップダウンリストの使い方を知っています。私の質問は、2つの異なるアドレスで動作するようにするための最良の方法でした。 – Terry

0

あなたはHTMLヘルパーを使用して考えがあります:あなたが唯一のデータベースのものをクエリが、それでもあなたはクリーン

のViewModelを見る保つこの方法はありますか?

Googleのクラスには、辞書のキャッシングを扱ういくつかのプライベート静的辞書変数があります。そのため、ドロップダウンがレンダリングされるたびに国のリスト(下のどのcountryDictionaryか)を取得する必要はありません。

public static MvcHtmlString CountrySelectFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string emptyText, object htmlAttributes) 
    { 
     SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = emptyText != null ? emptyText : "", Value = "" } }; 
     return htmlHelper.DropDownListFor(expression, emptyText != null ? SingleEmptyItem.Concat(new SelectList(countryDictionary, "Key", "Value")) : new SelectList(countryDictionary, "Key", "Value"), htmlAttributes); 
    } 

ここから、あなたはあなたがあなたのHTMLヘルパーを入れて名前空間を登録した後は、使用することができます:

<%: Html.CountrySelectFor(model => Model.HeadOffice.CountryId) %> 

ちょうどあなたの参照のために、ここでcountryListためのスニペット出ています。以下の「キャッシュ」の行はあなたのために存在しません。アプリケーションキャッシュを管理するために作成したカスタムクラスです。

private static Dictionary<int, string> countryList 
    { 
     get 
     { 
      IList<Models.Country> countries = Caching.HTTPCache.Get(Caching.Common.CountryCacheName) as IList<Models.Country>; 

      if (countries == null) 
      { 
       countries = Models.Country.Get(); //Loads all countries from the DB 
       Caching.HTTPCache.Add(Caching.Common.CountryCacheName, countries , new TimeSpan(0, 0, Caching.Common.CountryCacheDuration, 0, 0)); //Adds the results to the cache 
      } 

      return countries .ToDictionary(t => t.CountryId, t => t.CountryName); 
     } 
    } 
関連する問題