Visual Studio 2019 ドロップダウンを実装する方法を解説

プログラミング

(この記事は2022年7月9日が最終更新日です。)

自己紹介

この記事の作成はKazuが行っています。
本業ではエンジニアとして働きつつWebサービス開発を行っております。
副業でWebエンジニア・デザインを行っています。

エンジニアに欠かせないのが学習という名の自己投資です。

いろいろな学習方法があって正直どれを選べばよいのか悩みますよね・・・

いくつもある学習方法の中から私がオススメするのはUdemy!!

購入したコースが満足いく内容でなければ返金もしてくれるので損はありません。

Udemyを試してみる!

本記事ではVisual Studio 2019 .Net Framework 4.8 でドロップダウンの入力項目を実装する方法を初心者でも分かりやすいように画像を用いて解説していきます。

具体的にはDropDownListForの使い方を解説していきます。

ソースコードもコピペで動くように公開するので、一緒に手を動かしながら本記事を読んでいただけると嬉しいです。

皆さんのお役に立てば幸いです。

私も勉強しながらなので至らない点があればTwitterでコメントください。

また.Net Frameworkが初めての方は以下の記事から読むと理解がしやすいと思います。

開発環境
  • 開発環境:Visual Studio 2019
  • フレームワーク:.Net Framework 4.8
  • MVCモデル
  • DB:MySQL ←本記事では関係なし

事前準備

それでは早速始めていきましょう。

今回の実装のモデルクラスは以下の通りです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

namespace CalendarSample_MySQL.Models
{
    public class Reserve
    {
        public int Id { get; set; }

        [DisplayName("予約者名")]
        public string ReserveName { get; set; }

        [DisplayName("予約日付")]
        public DateTime ReserveDate { get; set; }
    }
}

今回はビューモデルを使用するのでReserve.csと同じようにCreateViewModel.csを作っていきます。

CreateViewModel.csのソースは以下の通りです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

namespace CalendarSample_MySQL.Models
{
    public class CreateViewModel
    {
        public int Id { get; set; }

        [DisplayName("予約者名")]
        public string Name { get; set; }

        [DisplayName("予約日付")]
        public string Date { get; set; }

        [DisplayName("予約時間")]
        public string Time { get; set; }
    }
}

ここまででドロップダウンを実装する準備が完了です。

ドロップダウンの実装

ビューを作成していきます。

スキャフォールディングで作成されるCreate.cshtmlは以下の通り。

@model CalendarSample_MySQL.Models.Reserve

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>


@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Reserve</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.ReserveName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ReserveName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ReserveName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ReserveDate, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ReserveDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ReserveDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

このコードを修正していきます。修正後のコードは以下の通り。

@model CalendarSample_MySQL.Models.CreateViewModel

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Reserve</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Date, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Date, new { htmlAttributes = new { @class = "form-control Date" } })
                @Html.ValidationMessageFor(model => model.Date, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Time, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownListFor(
                    model => model.Time,
                    new SelectListItem[] {
                    new SelectListItem() { Value="9:00", Text="9:00" },
                    new SelectListItem() { Value="10:00", Text="10:00" },
                    new SelectListItem() { Value="11:00", Text="11:00" },
                    new SelectListItem() { Value="12:00", Text="12:00" },
                    new SelectListItem() { Value="13:00", Text="13:00" },
                    new SelectListItem() { Value="14:00", Text="14:00" },
                    new SelectListItem() { Value="15:00 ", Text="15:00" }
                    },
                    "選択してください",
                    new { @class = "form-control" }
                    )
                @Html.ValidationMessageFor(model => model.Time, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-datetimepicker@2.5.20/build/jquery.datetimepicker.full.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js"></script>
<script type="text/javascript">
    $(function () {
        $(".Date").datepicker();
    });
</script>

解説

今回注目する点は

  • ビューモデルを受け取る処理
  • Html.DropDownListForに入力項目を変更

ビューモデルを受け取る処理

@model CalendarSample_MySQL.Models.CreateViewModel

ReserveからCreateViewModelに変更します。

Html.DropDownListForに入力項目を変更

@Html.DropDownListFor(
                    model => model.Time,
                    new SelectListItem[] {
                    new SelectListItem() { Value="9:00", Text="9:00" },
                    new SelectListItem() { Value="10:00", Text="10:00" },
                    new SelectListItem() { Value="11:00", Text="11:00" },
                    new SelectListItem() { Value="12:00", Text="12:00" },
                    new SelectListItem() { Value="13:00", Text="13:00" },
                    new SelectListItem() { Value="14:00", Text="14:00" },
                    new SelectListItem() { Value="15:00 ", Text="15:00" }
                    },
                    "選択してください",
                    new { @class = "form-control" }
                    )

@Html.EditorForだったところを@Html.DropDownListForに変えます。

SelectListItemはプルダウンに表示される選択肢を設定しています。

ここまでの処理でビューの実装はできました。

ビューモデルの項目はモデルクラスとは違うので、コントローラー側で編集してDBに登録していきます。

コントローラーのCreateメソッドを修正します。※抜粋してコードを紹介します。

// POST: Reserves/Create
        // 過多ポスティング攻撃を防止するには、バインド先とする特定のプロパティを有効にしてください。
        // 詳細については、https://go.microsoft.com/fwlink/?LinkId=317598 を参照してください。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,ReserveName,ReserveDate")] CreateViewModel createViewModel)
        {
            if (ModelState.IsValid)
            {
                Reserve reserve = new Reserve()
                {
                    Id = createViewModel.Id,
                    ReserveName = createViewModel.Name,
                    ReserveDate = DateTime.Parse(createViewModel.Date + " " + createViewModel.Time)
                };

                db.Reserves.Add(reserve);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(createViewModel);
        }

以下部分で受け取ったデータをReserveに設定して、DBに登録していきます。

Reserve reserve = new Reserve()
    {
        Id = createViewModel.Id,
        ReserveName = createViewModel.Name,
        ReserveDate = DateTime.Parse(createViewModel.Date + " " + createViewModel.Time)
    };

動作確認をする

こんな感じで実装出来ているかと思います。

ドロップダウンの選択肢をDBから取得する方法

先ほど紹介したドロップダウンの実装では、直接選択肢を作ったので実用的ではないかと思います。

ここからはドロップダウンの選択肢をDBから取得する方法を解説してきます。

ドロップダウンの選択肢ようにモデル作成していきます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;

namespace CalendarSample_MySQL.Models
{
    public class TimeTable
    {
        public int Id { get; set; }

        [DisplayName("パターン")]
        public int Pattern { get; set; }

        [DisplayName("時刻")]
        public DateTime Time { get; set; }
    }
}

コンテキストも修正しておきましょう。

using System;
using System.Data.Entity;
using System.Linq;

namespace CalendarSample_MySQL.Models
{
    public class Model1 : DbContext
    {
        public Model1()
            : base("name=Model1")
        {
        }

        public DbSet<Reserve> Reserves { get; set; }
        public DbSet<TimeTable> TimeTables { get; set; }

    }
}

ここからがDBから値を取得するために重要な処理になります。

まずはコントローラーで値を取得する処理を実装していきます。

// GET: Reserves/Create
public ActionResult Create()
{
    //ドロップダウンの選択肢を定義
    //ViewBagの使い方は"ViewBag.ServerOptions"とうい変数と理解する。引数で渡さなくてもグローバルで使える。
    ViewBag.ServerOptions = db.TiemTables.Select(s => new SelectListItem()
    {
        Text  = s.ReserveDate.ToString(),
        Value = s.ReserveDate.ToString()
    });

    return View();
}

DBからデータを取得し、ViewBagに設定する処理です。

続いてビューを修正していきます。※一部抜粋

<div class="form-group">
    @Html.LabelFor(model => model.Time, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(model => model.Time, (IEnumerable<SelectListItem>)ViewBag.ServerOptions, "選択してください", new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.Time, "", new { @class = "text-danger" })
    </div>
</div>

DropDownListForの引数を修正します。

動作確認をする

こんな感じで実装出来ているかと思います。

おわりに

本記事の内容は以上になります。

お役に立てば幸いです。

繰り返しになりますが、システムエンジニアとして生きていく上で勉強は欠かせません!
書籍を購入して勉強するのもいいですが専門書は高いし、質問もできません。
私はいつも世界最大級のオンライン学習サイトUdemyで学習を行っています。
Udemyでは具体的な方法を教えてくれるし質問も可能なのでとても学習しやすいと感じています。
セールも定期的に実施されています。90%オフの講義もたくさんあるのでセールのタイミングを狙って購入しています。

「Udemy」公式サイト

コメント

タイトルとURLをコピーしました