9.メイン画面-Form編

初めに

  Web Form のフィールドワークデータを扱う画面を示します。(画像をクリックすると、拡大表示します) それぞれ、検索前の画面(下記図面1)・検索後の画面(下記図面2)・新規の追加画面(下記図面3)になります。
これら以外にも、参照・更新・削除などの画面があります。フィールドワークデータは項目が多いため、それぞれ個別の処理のための画面を用意してあります。
 以下では、検索の前後の画面と新規の追加画面を取り上げます。

画面1
画面2
画面3

一覧画面

 一覧画面を構成するクラスは以下のものになります。また、検索前と検索後では同じ Web フォームを使用します。そのため、そのプログラム部分は大きくなりました。

  • Web フォーム
    • FieldworkList
      画面項目は、 FieldworkList.aspx
      プログラム部分は、 FieldworkList.aspx.cs
  • 問題領域クラス
    モデルクラスのうち、問題領域のデータを表現したクラスです
    • Area
      エリアを表現したクラスです
    • Major
      大分類データを表現したクラスです
    • Material
      フィールドワークデータを表現したクラスです
    • MaterialWindowCondition
      検索条件を表現したクラスです
    • Minor
      小分類データを表現したクラスです
    • Polygon
      エリアの多角形を表現したクラスです
    • Position
      緯度経度を表現したクラスです
  • データベースクラス
    モデルクラスのうち、データベース関連に対応したクラスです
    • AreaTable
      エリアテーブルに対応したクラスです
    • FieldworkDB
      今回使用するデータベースクラスです
    • MajorTable
      大分類テーブルに対応したクラスです
    • MaterialTable
      フィールドワークテーブルに対応したクラスです
    • MinorTable
      小分類テーブルに対応したクラスです

一覧画面の特徴-データ検索

 この画面では、複数の検索条件を指定して、「検索」ボタンのクリックでデータ検索が行われます。その場合のイベントハンドラは以下になります。

					
      FieldworkList.aspx.cs の一部分
1     protected void ReadButton_Click(object sender, EventArgs e)
2     {
3         MaterialWindowCondition cond = new MaterialWindowCondition();

4         if (MajorID.SelectedIndex > 0)
5             cond.MajorId = MajorID.SelectedValue;
6         if (MinorID.SelectedIndex > 0)
7             cond.MinorId = MinorID.SelectedValue;
8         cond.Title = InputTitle.Text;
9         cond.Place = InputPlace.Text;
10        if (StartDate.Text.Length > 0)
11        {
12            cond.StartDate = DateTime.Parse(StartDate.Text);
13        }
14        if (EndDate.Text.Length > 0)
15        { 
16            cond.EndDate = DateTime.Parse(EndDate.Text);
17        }

18        if (AreaID.SelectedIndex > 0)
19            cond.AreaId = AreaID.SelectedValue;

20        Session[ConditionSessionName] = cond;

21        FieldworkView.SelectedIndex = -1;
22        FieldworkView.PageIndex = 0;

23        DisplayGrid();
24    }
					
					

 1行目:検索ボタンクリック時のハンドラ定義です
 3~19行:検索条件クラスの設定をしています
 20行目:次のポストバック時に使用するために、検索条件をセッションに保存しています
 21~22行目:検索結果のリストの初期化処理です
 23行目:検索の実行とその結果の表示処理です(別メソッドになっています)

一覧画面の特徴-ページング

 検索結果のリストは、ページングされます。この処理は、標準の asp:GridView が持つ機能を利用しています。

					
      FieldworkList.aspx の一部分
1     <asp:GridView ID="FieldworkView" runat="server" AutoGenerateColumns="False" CssClass="table table-condensed table-bordered"
2       GridLines="None" CellSpacing="-1" ViewStateMode="Disabled" AllowPaging="True"
3       EnablePersistedSelection="true" OnPageIndexChanging="FieldworkList_PageIndexChanging"
4       OnRowDataBound="FieldworkList_RowDataBound" OnSelectedIndexChanged="FieldworkView_SelectedIndexChanged">
5         <SelectedRowStyle CssClass="success" />
6         <PagerSettings Mode="NumericFirstLast" Position="TopAndBottom" PageButtonCount="10" />
7         <PagerStyle BackColor="LightBlue" Height="30px" VerticalAlign="Bottom" HorizontalAlign="Center"
8           CssClass="pager-margin" />
9         <Columns>
10            <asp:BoundField DataField="Row_Number" HeaderText="No">
11                <HeaderStyle CssClass="p5 text-center" />
12            </asp:BoundField>
13            <asp:BoundField DataField="ID" HeaderText="ID">
14                <HeaderStyle CssClass="p5 text-center" />
15            </asp:BoundField>
16            <asp:BoundField DataField="MajorName" HeaderText="大分類">
17                <HeaderStyle CssClass="p10 text-center" />
18            </asp:BoundField>
19            <asp:BoundField DataField="MinorName" HeaderText="小分類">
20                <HeaderStyle CssClass="p10 text-center" />
21            </asp:BoundField>
22            <asp:BoundField DataField="Rdate" HeaderText="調査日" DataFormatString="{0:d}">
23                <HeaderStyle CssClass="p10 text-center" />
24            </asp:BoundField>
25            <asp:BoundField DataField="Place" HeaderText="調査場所">
26                <HeaderStyle CssClass="p20 text-center" />
27            </asp:BoundField>
28            <asp:BoundField DataField="IsMap" HeaderText="地図">
29                <HeaderStyle CssClass="p5 text-center" />
30                <ItemStyle CssClass="text-center" />
31            </asp:BoundField>
32            <asp:BoundField DataField="Photos" HeaderText="写真">
33                <HeaderStyle CssClass="p5 text-center" />
34                <ItemStyle CssClass="text-right" />>
35            </asp:BoundField>
36            <asp:BoundField DataField="Title" HeaderText="タイトル">
37                <HeaderStyle CssClass="p30 text-center" />
38            </asp:BoundField>
39            <asp:TemplateField HeaderStyle-CssClass="hidden" ItemStyle-CssClass="hidden">
40                <ItemTemplate>
41                    <asp:LinkButton ID="SelectButton" runat="server" CommandName="Select" Text="" Width="0%"
42                      Visible="True" />
43                </ItemTemplate>
44            </asp:TemplateField >
45        </Columns>
46    </asp:GridView>

      FieldworkList.aspx.cs の一部分
47    protected void FieldworkList_RowDataBound(object sender, GridViewRowEventArgs e)
48    {
49        if (e.Row.RowType == DataControlRowType.DataRow)
50        {
51            LinkButton btn = (LinkButton)(e.Row.FindControl("SelectButton"));
52            e.Row.Attributes["onClick"] = ClientScript.GetPostBackClientHyperlink(btn, "");
53        }
54    }

55    protected void FieldworkList_PageIndexChanging(object sender, GridViewPageEventArgs e)
56    {
57        FieldworkView.PageIndex = e.NewPageIndex;
58        FieldworkView.DataBind();
59    }
					
					

 1~4行目:リスト用コンポーネント asp:GridView の部分です
 9~45行目:リストの項目に対応した部分です
 47~54行目:リストの各1行が確定した場合のハンドラの定義です
 55~59行目:ページ番号が変更になった場合のハンドラの定義です

追加画面

 追加画面には多くの項目が有りますが、 html の画面構成としては単純です。この画面を構成するクラスは以下のものになります。

  • Web フォーム
    • NewFieldworkPage
      画面項目は、 NewFieldworkPage.aspx
      プログラム部分は、 NewFieldworkPage.aspx.cs
  • 問題領域クラス
    モデルクラスのうち、問題領域のデータを表現したクラスです
    • Area
      エリアを表現したクラスです
    • Image
      イメージファイルを表現したクラスです
    • Major
      大分類データを表現したクラスです
    • Material
      フィールドワークデータを表現したクラスです
    • MaterialWindowCondition
      検索条件を表現したクラスです
    • Minor
      小分類データを表現したクラスです
  • データベースクラス
    モデルクラスのうち、データベース関連に対応したクラスです
    • AreaTable
      エリアテーブルに対応したクラスです
    • FieldworkDB
      今回使用するデータベースクラスです
    • ImageTable
      イメージテーブルに対応したクラスです
    • MajorTable
      大分類テーブルに対応したクラスです
    • MaterialTable
      フィールドワークテーブルに対応したクラスです
    • MinorTable
      小分類テーブルに対応したクラスです

 写真ファイルを添付するためには、<input> タグを使用しています。そのボタンの表示を bootstrap のボタンの表示形式に合わせる方法は、 こちら をご覧ください。

追加画面の特徴-トランザクション

 フィールドワークデータの追加画面からは、以下の処理をトランザクションとして実行することが必要です。どれかの処理が失敗した場合は、 全体をロールバックする必要があります。

  • フィールドワークデータの追加
    1件分のフィールドワークデータを新規に追加することが必要です
  • イメージデータの追加
    指定された写真ファイルの数分、イメージテーブルに追加することが必要です
  • イメージファイルのアップロード
    指定された写真ファイルをアップロードして、保存することが必要です
            		
      NewFieldworkPage.aspx.cs の一部分
1     private bool flag;

2     protected void OkButton_Click(object sender, EventArgs e)
3     {
4         flag = true;

5         Execute();

6         if (flag)
7             Response.Redirect("FieldworkList.aspx?Update=1");
8     }

9     public override void DoAction()
10    {
11        Material obj = new Material();
12        obj.MajorId = MajorID.SelectedValue;
13        obj.MinorId = MinorID.SelectedValue;
14        obj.Title = InputTitle.Text;
15        obj.Keyword = InputKeyword.Text;
16        obj.Contents = InputContents.Text;
17        obj.Place = InputPlace.Text;
18        obj.Others = InputOthers.Text;
19        obj.RegisterDate = DateTime.Parse(ResearchDateHidden.Text);
20        if (InputAmount.Text.Length > 0)
21        {
22            int val;
23            if (int.TryParse(InputAmount.Text, out val))
24                obj.Amount = val;
25        }
26        obj.UnitId = UnitID.SelectedValue;
27        obj.Latitude = InputLatitude.Text;
28        obj.Longitude = InputLongitude.Text;

29        FieldworkDB database = new FieldworkDB();
30        MaterialTable table = new MaterialTable(database);

31        string sql = table.AppendSql(obj);
32        int id = -1;
33        if ((id = database.ExecuteThenReadId(sql)) < 0)
34        {
35            flag = false;
36            String msg = string.Format("{0}[{1}]", database.Result, database.ErrorCode);
37            throw new Exception(msg);
38        }

39        UploadImages(id, database);
40    }

41    private void UploadImages(int id, FieldworkDB database)
42    {
43        if (FileUpload.PostedFiles.Count == 0)
44            return;

45        string dir;
46        string dirFormat = "{0}\\{1}\\";
47        string[] args = new string[2];
48        args[0] = ConfigurationManager.AppSettings["TempDir"];
49        args[1] = "" + id;
50        dir = String.Format(dirFormat, args);
51        if (! Directory.Exists(dir))
52            Directory.CreateDirectory(dir);

53        ImageTable imageTable = new ImageTable(database);

54        int cnt = 1;
55        String sql, fileName;
56        Model.Image image = new Model.Image();
57        foreach (var file in FileUpload.PostedFiles)
58        {
59            if (Path.GetFileName(file.FileName).Length <= 0)
60                continue;

61            fileName = dir + cnt.ToString("000") + "_" + Path.GetFileName(file.FileName);
62            image.Name = fileName;
63            image.ItemId = id;
64            image.Sequence = cnt;

65            sql = imageTable.AppendSql(image);
66            if (database.Execute(sql) < 0)
67            {
68                flag = false;
69                String msg = string.Format("{0}[{1}]", database.Result, database.ErrorCode);
70                throw new Exception(msg);
71            }

72            file.SaveAs(fileName);
73            ++cnt;
74        }
75    }
            		
            		

 1行目:トランザクション処理の成功・不成功のフラグです
 2行目:追加ボタン用のハンドラの定義です
 4行目:トランザクションの結果を成功に設定します
 5行目:トランザクション処理を開始します
 6~7行目:トランザクションが成功した場合、初期状態に遷移します
 9行目:トランザクション本体の定義です
 11~28行目:フィールドワークデータを構築します
 29~30行目:データベース関連クラスの準備です
 32行目:自動附番されるフィールドワークデータの番号です
 33行目:フィールドワークデータの追加に失敗した場合です
 35行目:トランザクションの結果を失敗に変更します
 36~37行目:トランザクションをロールバックするために例外を投げます
 39行目:イメージファイル処理を別メソッドとして呼び出します
 41行目:イメージファイル処理の本体定義です
 43~44行目:添付ファイルが無い場合に終了します
 45~52行目:イメージファイル用フォルダーを準備します
 57~73行目:添付ファイルの数だけ処理を繰り返します
 59~64行目:イメージファイルのファイル名を構築します
 65~66行目:イメージファイルの追加に失敗した場合です
 68行目:トランザクションの結果を失敗に変更します
 69~70行目:トランザクションをロールバックするために例外を投げます
 72行目:イメージファイルを作成します