web-dev-qa-db-ja.com

MVC DropDownList SelectedValueが正しく表示されない

検索を試みましたが、問題を解決するものは見つかりませんでした。選択リストで選択済みとしてマークしたアイテムを表示しないドロップダウンリストがRazorビューにあります。以下は、リストに入力するコントローラーコードです。

var statuses  = new SelectList(db.OrderStatuses, "ID", "Name", order.Status.ID.ToString());
ViewBag.Statuses = statuses;
return View(vm);

これがViewコードです:

<div class="display-label">
   Order Status</div>
<div class="editor-field">
   @Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)
   @Html.ValidationMessageFor(model => model.StatusID)
</div>

ウォークスルーすると、ビューでも正しいSelectedValueが表示されますが、DDLでは、選択された値に関係なく、常にリストの最初の項目が表示されます。 DDLをデフォルトでSelectValueにするために私が間違っていることを誰かが指摘できますか?

20
azorr

DropDownListForヘルパーが最初の引数として渡したラムダ式を使用し、特定のプロパティの値を使用するため、SelectListコンストラクターの最後の引数(選択した値IDを渡すことができることを望んでいます)は無視されます。

したがって、これを行うための醜い方法を次に示します。

モデル:

public class MyModel
{
    public int StatusID { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        ViewBag.Statuses = statuses;

        var model = new MyModel();
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

見る:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, (SelectList)ViewBag.Statuses)

実際のビューモデルを使用した正しい方法は次のとおりです。

型番

public class MyModel
{
    public int StatusID { get; set; }
    public IEnumerable<SelectListItem> Statuses { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // TODO: obviously this comes from your DB,
        // but I hate showing code on SO that people are
        // not able to compile and play with because it has 
        // gazzilion of external dependencies
        var statuses = new SelectList(
            new[] 
            {
                new { ID = 1, Name = "status 1" },
                new { ID = 2, Name = "status 2" },
                new { ID = 3, Name = "status 3" },
                new { ID = 4, Name = "status 4" },
            }, 
            "ID", 
            "Name"
        );
        var model = new MyModel();
        model.Statuses = statuses;
        model.StatusID = 3; // preselect the element with ID=3 in the list
        return View(model);
    }
}

見る:

@model MyModel
...    
@Html.DropDownListFor(model => model.StatusID, Model.Statuses)
47
Darin Dimitrov

各ビューのビューモデルを作成します。このようにすると、画面に必要なものだけが含まれます。このコードをどこで使用しているのかわからないので、新しい注文を追加するためのCreateビューがあるとします。

作成ビューの新しいビューモデルを作成します。

public class OrderCreateViewModel
{
     // Include other properties if needed, these are just for demo purposes

     // This is the unique identifier of your order status,
     // i.e. foreign key in your order table
     public int OrderStatusId { get; set; }
     // This is a list of all your order statuses populated from your order status table
     public IEnumerable<OrderStatus> OrderStatuses { get; set; }
}

注文状況クラス:

public class OrderStatus
{
     public int Id { get; set; }
     public string Name { get; set; }
}

作成ビューでは、次のようになります。

@model MyProject.ViewModels.OrderCreateViewModel

@using (Html.BeginForm())
{
     <table>
          <tr>
               <td><b>Order Status:</b></td>
               <td>
                    @Html.DropDownListFor(x => x.OrderStatusId,
                         new SelectList(Model.OrderStatuses, "Id", "Name", Model.OrderStatusId),
                         "-- Select --"
                    )
                    @Html.ValidationMessageFor(x => x.OrderStatusId)
               </td>
          </tr>
     </table>

     <!-- Add other HTML controls if required and your submit button -->
}

Createアクションメソッド:

public ActionResult Create()
{
     OrderCreateViewModel viewModel = new OrderCreateViewModel
     {
          // Here you do database call to populate your dropdown
          OrderStatuses = orderStatusService.GetAllOrderStatuses()
     };

     return View(viewModel);
}

[HttpPost]
public ActionResult Create(OrderCreateViewModel viewModel)
{
     // Check that viewModel is not null

     if (!ModelState.IsValid)
     {
          viewModel.OrderStatuses = orderStatusService.GetAllOrderStatuses();

          return View(viewModel);
     }

     // Mapping

     // Insert order into database

     // Return the view where you need to be
}

これは、送信ボタンをクリックしたときに選択内容を保持し、エラー処理のために作成ビューにリダイレクトされます。

これがお役に立てば幸いです。

2
Brendan Vogt

モデルで宣言する場合、戻り値の選択値は文字列であり、整数ではないことを確認してください。

例:

public class MyModel
{
    public string StatusID { get; set; }
}
1
p.sturge

私にとって、問題は大きなcssパディング数(ドロップダウンフィールド内の上下のパディング)が原因でした。基本的に、アイテムは表示されていましたが、かなり下にあるため表示されませんでした。パディング数を小さくして修正しました。

0
JPTugirimana

それが誰かを助けるために私はこれを残します。私は非常によく似た問題を抱えており、どの回答も役に立ちませんでした。

ViewDataに、ラムダ式のセレクターと同じ名前のプロパティがあり、基本的にはViewData["StatusId"]何かに設定します。

ViewDataの匿名プロパティの名前を変更した後、DropDownListヘルパーは期待どおりに機能しました。

奇妙ですが。

0
Alberto Sadoc

私の解決策はこれでした...現在選択されているアイテムはProjectManagerIDです。

見る:

@Html.DropDownList("ProjectManagerID", Model.DropDownListProjectManager, new { @class = "form-control" })

モデル:

public class ClsDropDownCollection
{
   public List<SelectListItem> DropDownListProjectManager { get; set; }
   public Guid ProjectManagerID { get; set; }
}

ドロップダウンを生成:

public List<SelectListItem> ProjectManagerDropdown()
{
    List<SelectListItem> dropDown = new List<SelectListItem>();
    SelectListItem listItem = new SelectListItem();

    List<ClsProjectManager> tempList = bc.GetAllProductManagers();           

    foreach (ClsProjectManager item in tempList)
    {
        listItem = new SelectListItem();
        listItem.Text = item.ProjectManagerName;
        listItem.Value = item.ProjectManagerID.ToString();
        dropDown.Add(listItem);
    }
    return dropDown;
}
0
Skak2000