ASP.NET {Article001}

説明文の表示 ライブデモを見る▶
ようこそ「ASP.NET」へ...

ASP.NET: ListViewを使用してAccessのレコードを追加・削除・編集・表示する

このサンプルではASP.NETのデータコントロールListViewを使用してAccessのデータベースにレコードを追加・削除・編集・表示します。 Accessのデータベース(Stats.accdb)とテーブル(Stats, Category)の作成手順についてはMS AccessのArticle001を参照してください。 ASP.NET 4.xではAccessDataSourceコントールが使用できないのでこのサンプルではObjectDataSourceコントロールを使用してAccessのテーブルをバインドします。 新規レコードを追加するにはListViewから[Add New]ボタンをクリックします。ListViewに表示されているレコードを削除するには[Delete]ボタンをクリックします。 レコードを削除するときに念のために再度確認する機能を追加するにはJavaScript/jQueryの記事Article004を参照してください。 レコードを編集(修正)するには[Edit]ボタンをクリックします。

このサンプルでは新規レコードを追加するときやレコードを編集するときに入力したデータの検証(チェック)を一切行っていません。 入力したデータを検証(チェック)する機能を追加するにはArticle005を参照してください。 レコードを追加・編集・削除したときに処理の結果を表示する機能を追加するにはArticle006を参照してください。 ListViewにページング機能を追加するにはArticle003を参照してください。 ListViewに表示されているレコードを並べ替える機能を追加するにはArticle002を参照してください。 ListViewから新規レコードを追加するとき「Category」を手入力ではなくDropDownListから選択する機能を追加するにはArticle004を参照してください。 ListViewに表示されている行を選択する機能を追加するにはArticle007を参照してください。

作成手順

  1. VS2019(Visual Studio 2019 or Visual Studio 2022)を起動したら新規のWebフォーム「Article001.aspx」を作成します。 Webフォームのヘッダータグ内(<head>...</head>)にLINKタグを追加してスタイルシートのファイル「StyleSheet.css」を取り込みます。
    
    Article001.aspx:
    
    <head runat="server">
        <title>ASP.NET: ListViewを使用してAccessのレコードを追加・削除・編集・表示する</title>
        <link href="../../../StyleSheet.css" rel="stylesheet" />
    </head>
    
    スタイルシートのファイルには以下のようなCSSを定義します。
    
    StyleSheet.css:
    
    /* ListView */
    
    /* ListView Top/Bottom Pager Row */
    
    table tr td.listViewPager {
        text-align: center;
        background-color: #CCCCCC;
        color: #000000;
    }
    
        table tr td span.listViewPagerLeft {
            float: left;
            text-align: left;
        }
    
        table tr td span.listViewPagerRight {
            float: right;
            text-align: right;
        }
    
    /* ListView Data Table */
    
    table.listView {
        background-color: #FFFFFF;
        border-collapse: collapse;
        border-color: #999999;
        border-style: none;
        border-width: 1px;
        font-size: smaller;
    }
    
    
        /* ListView Data Table Header */
    
        table.listView tr:first-child {
            background-color: #DCDCDC;
            color: #000000;
        }
    
            table.listView tr.listViewHeader th.listViewSortUp:after {
                content: "▲";
                color: Red;
            }
    
            table.listView tr.listViewHeader th.listViewSortDown:after {
                content: "▼";
                color: Red;
            }
    
            /* ListView Data Table Rows */
    
            table.listView tr:nth-child(even) {
                background: #FFFFFF;
            }
    
            table.listView tr:nth-child(odd) {
                background: #F0F0F0;
            }
    
            table.listView tr.listViewItem {
        
            }
    
            table.listView tr..listViewEditItem {
                background-color: #B8D1F3;
            }
    
            table.listView tr..listViewInsertItem {
                background-color: #FFF5F6;
            }
    
    
            table.listView tr..listViewItemSelect {
                background-color: #B8D1F3;
            }
    
    
    /* Misc CSS */
    
    .listViewTitle {
        text-decoration: none;
    }
    
    .alignLeft {
        text-align: left;
    }
    
    .alignTopLeft {
        text-align: left;
        vertical-align: top;
    }
    
    .alignRight {
        text-align: right;
    }
    
    .alignTopRight {
        text-align: right;
        vertical-align: top;
    }
    
    .alignCenter {
        text-align: center;
    }
    
    .alignTopCenter {
        text-align: center;
        vertical-align: top;
    }
    
    .alignTop {
        vertical-align: top;
    }
    
  2. VS2019のツールボックスからListViewコントロールをドッラッグ&ドロップしてWebフォームに配置します。 ListViewにDataKeyNamesプロパティを追加してAccessのStatsテーブルの主キーのフィールド名「Url」を設定します。 DataSourceIDプロパティを追加したら「ObjectDataSource1ListView」を設定します。 ObjectDataSourceの作成手順については後述します。 InsertItemPositionプロパティを追加したら「LastItem」を設定します。 「LastItem」を設定するとListViewの最終行にレコード追加専用の行が表示されます。 最後にOnPreRenderとOnItemDataBoundイベントを追加します。これらのイベント処理は後述します。
    
    <asp:ListView ID="ListView1" runat="server" 
        DataKeyNames="Url" 
        DataSourceID="ObjectDataSource1ListView" 
        InsertItemPosition="LastItem"
        OnPreRender="ListView1_PreRender"         
        OnItemDataBound="ListView1_ItemDataBound">
        ===ここには後述するLayoutTemplate、ItemTemplate、EditItemTemplate、InsertItemTemplate、EmptyDataTemplateを挿入する===
    </asp:ListView>
    
  3. ListViewコントロールに<LayoutTemplate>...</LayoutTemplate>を追加してListViewのヘッダーを定義します。 ここではListViewのヘッダー「th」タグで「Command」「Url」「Title」「Category」「View Count」「Date Last Viewed」の列を定義します。 HTMLの「table id="itemPlaceholderContainer"」タグにはclass属性を追加して「listView」を設定します。 <tr>...</tr>の「itemPlaceholder」には後述するItemTemplate、EditItemTemplate、InsertItemTemplate、EmptyDataTemplateが挿入されます。
    
    <LayoutTemplate>
        <table runat="server" width="100%">
            <tr runat="server">
                <td runat="server">
                    <table id="itemPlaceholderContainer" runat="server" border="1" class="listView">
                        <tr runat="server" id="listViewHeader">
                            <th runat="server">Command</th>
                            <th runat="server">Url</th>
                            <th runat="server">Title</th>
                            <th runat="server">Category</th>
                            <th runat="server">View Count</th>
                            <th runat="server">Date Last Viewed</th>                           
                        </tr>
                        <tr id="itemPlaceholder" runat="server"></tr>
                    </table>
                </td>
            </tr>
        </table>
    </LayoutTemplate>
    
  4. ListViewコントロールに<ItemTemplate>...</ItemTemplate>を追加します。 HTMLの「tr」タグにはclass属性を追加して「listViewItem」を設定します。 ツールボックスからButtonコントロールをドラッグ&ドロップして[Edit]と[Delete]のボタンを「Command」の列(カラム)に配置します。 [Edit]ボタンのCommandNameプロパティには「Edit」、[Delete]ボタンのCommandNameプロパティには「Delete」を設定します。 ASP.NETはこのCommandNameに設定した値を元に編集と削除処理を実行します。 CssClassプロパティには「listViewButton」を設定します。 「View Count」列の「td」タグにはclass属性を追加して「alignRight」を設定します。これでViewCountが右詰めで表示されます。 「Date Last Viewed」の列の「td」タグにはclass属性を追加して「alignCenter」を設定します。これで日付がセンタリングされて表示されます。 HTMLのTR、TDタグのCSSの設定はHTML/CSSのArticle004を参照してください。

    「Url」「Title」、「Category」、「View Count」、「Date Last Viewed」の列に配置したLabelコントロールのTextプロパティにはASP.NETのEval()メソッドでAccessのStatsテーブルのフィールドをバインドします。 ASP.NETのサーバー側で行う処理を記述には「<%#...%>」で囲って記述します。Statsテーブルの「Url」フィールドをバインドするには「<%# Eval("Url") %>」のように記述します。 バインドするフィールドをフォーマットして表示するには「<%# Eval("DateLastViewed", "{0:yyyy/MM/dd}") %>」のように記述します。ここでは日付を「yyyy/MM/dd」の書式でフォーマットしています。
    
    <ItemTemplate>
        <tr class="listViewItem">
            <td>
                <asp:Button ID="EditButton" runat="server" CssClass="listViewButton" CommandName="Edit" Text="Edit" />
                <asp:Button ID="DeleteButton" runat="server" CssClass="listViewButton" CommandName="Delete" Text="Delete" />
            </td>
            <td>
                <asp:Label ID="UrlLabel" runat="server" Text='<%# Eval("Url") %>' />
            </td>
            <td>
                <asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
            </td>
            <td>
                <asp:Label ID="CategoryLabel" runat="server" Text='<%# Eval("Category") %>' />
            </td>
            <td class="alignRight">
                <asp:Label ID="ViewCountLabel" runat="server" Text='<%# Eval("ViewCount","{0:n0}") %>' />
            </td>
            <td class="alignCenter">
                <asp:Label ID="DateLastViewedLabel" runat="server" Text='<%# Eval("DateLastViewed","{0:yyyy/MM/dd}") %>' />
            </td>
        </tr>
    </ItemTemplate>
    
  5. ListViewコントロールに<EditItemTemplate>...</EditItemTemplate>を追加します。 HTMLの「tr」タグにはclass属性を追加して「listViewEditItem」を設定します。 ツールボックスからButtonのコントロールをドラッグ&ドロップして[Update]と[Cancel]のボタンを「Command」の列に配置します。 [Update]ボタンのCommandNameプロパティには「Update」、[Cancel]ボタンのCommandNameプロパティには「Cancel」を設定します。 CssClassプロパティには「listViewButton」を設定します。[Update]コマンドにはさらにBackColorプロパティを追加してボタンの背景色をオレンジ色(Orange)に設定します。

    「Url」のフィールドはStatsテーブルの主キーなので変更できないためツールボックスからLabelコントロールを配置してEval()メソッドでバインドします。 「Title」「Category」「ViewCount」「DateLastViewed」のフィールドはツールボックスからTextBoxコントロールを配置してBind()メソッドでバインドします。フィールドを更新するときはEval()ではなくBind()を使用します。 TextBoxのColumnsプロパティには入力領域の長さを設定します。
    
    <EditItemTemplate>
        <tr class="listViewEditItem">
            <td>
                <asp:Button ID="UpdateButton" runat="server" CssClass="listViewButton" BackColor="Orange" CommandName="Update" Text="Update" />
                <asp:Button ID="CancelButton" runat="server" CssClass="listViewButton" CommandName="Cancel" Text="Cancel" />
            </td>
            <td>
                <asp:Label ID="UrlLabel" runat="server" Text='<%# Eval("Url") %>' />
            </td>
            <td>
                <asp:TextBox ID="TitleTextBox" runat="server" Columns="100" Text='<%# Bind("Title") %>' />
            </td>
            <td>
                <asp:TextBox ID="CategoryTextBox" runat="server" Columns="10" Text='<%# Bind("Category") %>' />
            </td>
            <td>
                <asp:TextBox ID="ViewCountTextBox" runat="server" Columns="5"  Text='<%# Bind("ViewCount") %>' />
            </td>
            <td>
                <asp:TextBox ID="DateLastViewedTextBox" runat="server" Columns="8"  Text='<%# Bind("DateLastViewed") %>' />
            </td>                 
        </tr>
    </EditItemTemplate>
    
  6. ListViewコントロールに<EmptyDataTemplate>...</EmptyDataTemplate>を追加したらHTMLのTABLE、TR、TDタグを配置します。 <td>...</td>内には「Stats table is empty...」を追加します。 EmptyDataTemplateで定義したデータはAccessのStatsテーブルが空のときに表示されます。
    
    <EmptyDataTemplate>
        <table runat="server">
            <tr>
                <td>Stats table is empty...</td>
            </tr>
        </table>
    </EmptyDataTemplate>
    
  7. ListViewコントロールに<InsertItemTemplate>...</InsertItemTemplate>を追加します。 HTMLの「tr」タグにはclass属性を追加して「listViewInsertItem」を設定します。 ツールボックスからButtonのコントロールをドラッグ&ドロップして[Add New]ボタンを「Command」の列に配置します。 [Add New]ボタンのCommandNameプロパティには「Insert」を設定します。CssClassプロパティには「listViewButton」を設定します。 さらにBackColorプロパティを追加してボタンの背景色をオレンジ色(Orange)に設定します。

    「Url」、「Title」「Category」「ViewCount」「DateLastViewed」のフィールドはツールボックスからTextBoxコントロールを配置してBind()メソッドでバインドします。 TextBoxのColumnsプロパティには入力領域の長さを設定します。

    「Url」フィールドはStatsテーブルの主キーに設定されているためユニークなUrlを入力する必要があります。 このサンプルでは入力データの検証を行っていません。入力した「Url」がユニークかどうかをチェックする方法についてはArticle005を参照してください。

    
    <InsertItemTemplate>
        <tr class="listViewInsertItem">
            <td class="alignCenter">
                <asp:Button ID="InsertButton" runat="server" CssClass="listViewButton" BackColor="Orange" CommandName="Insert" Text="Add New" />
            </td>
            <td>
                <asp:TextBox ID="UrlTextBox" runat="server" Columns="40" Text='<%# Bind("Url") %>' />
            </td>
            <td>
                <asp:TextBox ID="TitleTextBox" runat="server" Columns="100" Text='<%# Bind("Title") %>' />
            </td>
            <td>
                <asp:TextBox ID="CategoryTextBox" runat="server"  Columns="10" Text='<%# Bind("Category") %>' />
            </td>
            <td>
                <asp:TextBox ID="ViewCountTextBox" runat="server"  Columns="5" Text='<%# Bind("ViewCount") %>' />
            </td>
            <td class="alignCenter">
                <asp:TextBox ID="DateLastViewedTextBox" runat="server"  Columns="8" Text='<%# Bind("DateLastViewed") %>' />
            </td>                 
        </tr>
    </InsertItemTemplate>
    
    TIP:TextBoxにフォーカスが移動したときにフォーカスが移動したことを強調するためのCSSを紹介します。 スタイルシートファイル(StyleSheet.css)に以下のようなCSSを追加するとTextBoxにフォーカスが移動するとTextBoxを「淡い青」で囲みます。実際の効果は「Live DEMO」で確認してください。
    
    StyleSheet.css:
    
    input[type=text], textarea {
        -webkit-transition: all 0.30s ease-in-out;
        -moz-transition: all 0.30s ease-in-out;
        -ms-transition: all 0.30s ease-in-out;
        -o-transition: all 0.30s ease-in-out;
        outline: none;
        padding: 3px 0px 3px 3px;
        margin: 5px 1px 3px 0px;
        border: 1px solid #DDDDDD;
    }
    
        input[type=text]:focus, textarea:focus {
            box-shadow: 0 0 5px rgba(81, 203, 238, 1);
            padding: 3px 0px 3px 3px;
            margin: 5px 1px 3px 0px;
            border: 1px solid rgba(81, 203, 238, 1);
        }
    
  8. ツールボックスからObjectDataSourceコントロールをドラッグ&ドロップしてWebフォームに配置します。 IDプロパティにはListViewコントロールのDataSourceIDプロパティに設定した名前「ObjectDataSource1ListView」を設定します。 SelectMethodプロパティにはListViewにAccessのStatsテーブルからすべてのレコードを読み込むメソッド「SelectAllStatsDataTable」を設定します。 UpdateMethod、DeleteMethod、InsertMethodプロパティにはListViewに表示されているレコードを編集、削除、挿入(新規登録)するメソッドを設定します。 TypeNameプロパティにはこれらのメソッドが記述されているクラスのNameSpace(名前空間)を設定します。

    DeleteParameters、InsertParameters、UpdateParametersには、DeleteStatsCommand()、InsertStatsCommand()、UpdateStatsCommand()メソッドに渡す引数(名前、データ型)を定義します。 たとえば、<DeleteParameters>...</DeleteParameters>には<asp:Parameter Name="Url" Type="String" />を追加して DeleteStatsCommand()メソッドに渡す引数名(Url)とデータ型(String)を定義します。
    
    public static DataTable SelectAllStatsDataTable()
    {
        :::::		
    }
    
    public static int UpdateStatsCommand(string Title, string Category, int ViewCount, DateTime DateLastViewed, string Url)
    {
        :::::
    }
    
    public static int DeleteStatsCommand(string Url)
    {
        :::::
    }
    
    public static int InsertStatsCommand(string Url, string Title, string Category, int ViewCount, DateTime DateLastViewed)
    {
        :::::
    }
    
    
    <asp:ObjectDataSource ID="ObjectDataSource1ListView" runat="server"     
        SelectMethod="SelectAllStatsDataTable"  
        UpdateMethod="UpdateStatsCommand"
        DeleteMethod="DeleteStatsCommand"
        InsertMethod="InsertStatsCommand"
        TypeName="asp4x.AccessDb.AspNet.Stats">
        <DeleteParameters>
            <asp:Parameter Name="Url" Type="String" />
        </DeleteParameters>
        <InsertParameters>
            <asp:Parameter Name="Url" Type="String" />
            <asp:Parameter Name="Title" Type="String" />
            <asp:Parameter Name="Category" Type="String" />
            <asp:Parameter Name="ViewCount" Type="Int32" />
            <asp:Parameter Name="DateLastViewed" Type="DateTime" />
        </InsertParameters>
        <UpdateParameters>
            <asp:Parameter Name="Title" Type="String" />
            <asp:Parameter Name="Category" Type="String" />
            <asp:Parameter Name="ViewCount" Type="Int32" />
            <asp:Parameter Name="DateLastViewed" Type="DateTime" />
            <asp:Parameter Name="Url" Type="String" />
        </UpdateParameters>
    </asp:ObjectDataSource>
    
  9. VS2019から新規クラス「Stats.cs」を作成したら以下のNameSpace(名前空間)を追加します。 そしてStatsクラスにはprivateな定数「ssCSname」を追加してWeb.configファイルのconnectionStringセクションに定義されているAccessのデータベース(Stats.accdb)の 接続文字列の名前「add name="AspNetStatsAccDbConnectionString"...」を定義します。 データベースの接続文字列は「add connectionString="Provider=Microsoft.ACE.OleDb.12.0;Data Source=C:\...\Stats.accdb"」に定義されています。
    
    Stats.cs:
    
    using System.Data;
    using System.Data.OleDb;
    using System.Configuration;
    
    namespcae asp4x.AccessDb.AspNet
    {
        public class Stats
        {
    	    private const string ssCSname = "AspNetStatsAccDbConnectionString";  // Stats.accdb Connection String Name
        }
    }
    
    
    Web.config:
    
    <configuration>
    	<connectionStrings>
    		<add name="AspNetStatsAccDbConnectionString"
    			connectionString="Provider=Microsoft.ACE.OleDb.12.0;Data Source=C:\●●●\Stats.accdb"
    			providerName="System.Data.OleDb" />
    	</connectionStrings>	
    </configuration>
    
  10. Stats.csクラスにAccessのStatsテーブルからレコードを抽出するメソッド「SelectAllStatsDataTable()」を追加します。 Statsテーブルからレコードを抽出するにはSQLの「SELECT」コマンドを使用します。Statsテーブルのすべてのフィールドを抽出には「*」を使用します。 特定のフィールドのみ抽出するときはフィールド名をコンマ区切りで「SELECT Url, Title, Category」のように記述します。 Statsテーブルからレコードを絞り込むには「WHERE」句を追加します。ここではすべてのレコードを抽出するので「WHERE」句は使用しません。 Statsテーブルから抽出したレコードを並べ替えるには「ORDER BY」句を使用します。ここでは「Url」フィールドを昇順(ASCending Order)に並べ替えています。「Url ASC」の「ASC」は省略できます。 降順(DESCending Order)に並べ替えるには「Url DESC」のように記述します。

    AccessのADO.NETを使用してStatsテーブルからレコードを抽出するには、OleDbConnectionオブジェクトのOpen()メソッドでAcccessのデータベース(Stats.accdb)を開きます。 AccessのStats.accdbデータベースの接続情報はWeb.configファイルのconnectionStringsセクションに定義されているので、 ConfigurationManagerオブジェクトのConnectionStringsコレクションから connectionStringsセクションの「add name="AspNetStatsAccDbConnectionString" ...」に定義した接続文字列の名前「AspNetStatsAccDbConnectionString」を指定して取得します。 データベースはOleDbAdapterのFill()メソッドを実行したときに自動的に接続されます。明示的に接続するにはOleDbConnectionのOpen()メソッドを使用します。 AccessのデータベースからStatsテーブルのレコードを抽出するにはOleDbAdapterのFill()メソッドを使用します。 Fill()メソッドが使用するSQLのSELECTコマンドは、OleDbCommandオブジェクトを使用して作成します。 「new OleDbCommand(strSQL, con)」を実行してSELECTコマンド用のOleDbCommandオブジェクトを作成したらOleDbDataAdapterのSelectCommandプロパティに設定します。

    OleDbAdapterのFill(dt)メソッドを実行するとStatsテーブルから抽出したすべてのレコードがDataTableオブジェクトに格納されます。 Accessのデータベースから複数のテーブルを抽出するときは、「DataSet」オブジェクトを作成してOleDbAdapterのFill()メッソドでは引数にDataSetのオブジェクトを指定します。 具体的には「DataSet ds new DataSet(); da.Fill(ds, "Stats")」のように記述します。 DataTableにStatsテーブルのすべてのレコードを格納したらコール元に戻り値としてDataTableを返します。
    
    Stats.cs:
    
    private const string ssCSname = "AspNetStatsAccDbConnectionString";  // Stats.accdb Connection String Name
    
    public static DataTable SelectAllStatsDataTable()
    {
        string strCS = ConfigurationManager.ConnectionStrings[ssCSname].ConnectionString;
        using (OleDbConnection con = new OleDbConnection(strCS))
        {
            string strSQL = "SELECT * FROM Stats ORDER BY Url";
    
            OleDbDataAdapter da = new OleDbDataAdapter();
            da.SelectCommand = new OleDbCommand(strSQL, con);
            DataTable dt = new DataTable("Stats");
            da.Fill(dt);
            dt.PrimaryKey = new DataColumn[] { dt.Columns["Url"] };
    
            return dt;
        }
    }
    
  11. Stats.csクラスにAccessのStatsテーブルのレコードを更新するメソッド「UpdateStatsCommand()」を追加します。 Statsテーブルのレコードを更新するにはSQLの「UPDATE」コマンドを使用します。 更新するレコードのフィールドは「SET」句に「Title = ?, Category = ?」のようにコンマ区切りで記述します。 更新するレコードを絞り込むには「WHERE」句を追加します。ここでは「WHERE Url = ?」を追加してレコードを絞り込んでいます。

    更新するフィールドの値はOleDbCommandオブジェクトのParametersコレクションにParameterオブジェクトを追加して設定します。 Parameterオブジェクトの引数には「名前」「データ型」「列の長さ」「ソースの列名」を指定します。 たとえば、UPDATEコマンドに記述した「Title = ?」の「?」に値を代入するには「cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Title").Value = Title」のように記述します。 SQL ServerのADO.NETは名前指定パラメータ(Named Parameters)をサポートしているので「cmd.Parameters.Add("@Title", OleDbType.VarWChar, 255, "Title").Value = Title」のように記述できます。 しかし、AccessのADO.NETは位置指定パラメータ(Positional Parameters)なので「?」を使用します。したがって、OleDbCommandのParametersコレクションにParameterオブジェクトを追加するときは、 SQLのUPDATEコマンドに指定した順番にParameterを追加する必要があります。

    Statsテーブルのレコードを更新するには、OleDbConnectionのOpen()メソッドを実行してデータベースを開きます。 そしてOleDbCommandのExecuteNonQuery()メソッドを実行してレコードを更新します。ExecuteNonQuery()の戻り値には更新したレコードの件数が返ります。
    
    Stats.cs:
    
    public static int UpdateStatsCommand(string Title, string Category, int ViewCount, DateTime DateLastViewed, string Url)
    {
        string strCS = ConfigurationManager.ConnectionStrings[ssCSname].ConnectionString;
        using (OleDbConnection con = new OleDbConnection(strCS))
        {
            string strSQL = "UPDATE Stats SET Title = ?, Category = ?, ViewCount = ?, DateLastViewed = ? WHERE Url = ?";
            OleDbCommand cmd = new OleDbCommand(strSQL, con);
    
            cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Title").Value = Title;
            cmd.Parameters.Add("?", OleDbType.VarWChar, 50, "Category").Value = Category;
            cmd.Parameters.Add("?", OleDbType.Integer, 8, "ViewCount").Value = ViewCount;
            cmd.Parameters.Add("?", OleDbType.Date, 8, "DateLastViewed").Value = DateLastViewed;
            cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Url").Value = Url;           
    
            con.Open();
            int intRowsAffected = cmd.ExecuteNonQuery();
            return intRowsAffected;
        }
    }
    
  12. Stats.csクラスにAccessのStatsテーブルからレコードを削除するメソッド「DeleteStatsCommand()」を追加します。 Statsテーブルからレコードを削除するにはSQLの「DELETE」コマンドを使用します。 削除するレコードは「WHERE」句に指定します。ここでは「WHERE Url = ?」を追加して削除するレコードを特定しています。

    WHERE句の「Url = ?」に値を代入するには「cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Url").Value = Url」のように記述します。 Statsテーブルのレコードを削除するには、OleDbConnectionのOpen()メッソドを実行してデータベースを開きます。 そしてOleDbCommandのExecuteNonQuery()メッソドを実行してレコードを削除します。ExecuteNonQuery()の戻り値には削除したレコードの件数が返ります。
    
    Stats.cs:
    
    public static int DeleteStatsCommand(string Url)
    {
        string strCS = ConfigurationManager.ConnectionStrings[ssCSname].ConnectionString;
        using (OleDbConnection con = new OleDbConnection(strCS))
        {
            string strSQL = "DELETE FROM Stats WHERE Url = ?";
            OleDbCommand cmd = new OleDbCommand(strSQL, con);
    
            cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Url").Value = Url;
    
            con.Open();
            int intRowsAffected = cmd.ExecuteNonQuery();
            return intRowsAffected;
        }
    }
    
  13. Stats.csクラスにAccessのStatsテーブルにレコードを追加(挿入)するメソッド「InsertStatsCommand()」を追加します。 Statsテーブルにレコードを追加(挿入)するにはSQLの「INSERT」コマンドを使用します。 「INTO」句にはテーブル名「Stats」と括弧内「(Url, Title, Category, ...)」 にフィールド名をコンマ区切りで指定します。 「VALUES」句にはフィールドの値を代入する「?」をコンマ区切りで指定します。

    追加するレコードのフィールドに値を代入するには「cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Url").Value = Url」のように記述します。 Accessのパラメータは位置指定パラメータなのでINSERTコマンドの括弧内「(Url, Title,...)」に指定した順番にパラメータに値を代入する必要があります。

    Statsテーブルにレコードを追加するには、OleDbConnectionのOpen()メッソドを実行してデータベースを開きます。 そしてOleDbCommandのExecuteNonQuery()メッソドを実行してレコードを追加します。ExecuteNonQuery()の戻り値には追加したレコードの件数が返ります。
    
    Stats.cs:
    
    public static int InsertStatsCommand(string Url, string Title, string Category, int ViewCount, DateTime DateLastViewed)
    {
        string strCS = ConfigurationManager.ConnectionStrings[ssCSname].ConnectionString;
        using (OleDbConnection con = new OleDbConnection(strCS))
        {
            string strSQL = "INSERT INTO Stats (Url, Title, Category, ViewCount, DateLastViewed) VALUES (?, ?, ?, ?, ?)";
            OleDbCommand cmd = new OleDbCommand(strSQL, con);
    
            cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Url").Value = Url;
            cmd.Parameters.Add("?", OleDbType.VarWChar, 255, "Title").Value = Title;
            cmd.Parameters.Add("?", OleDbType.VarWChar, 50, "Category").Value = Category;
            cmd.Parameters.Add("?", OleDbType.Integer, 8, "ViewCount").Value = ViewCount;
            cmd.Parameters.Add("?", OleDbType.Date, 8, "DateLastViewed").Value = DateLastViewed;         
    
            con.Open();
            int intRowsAffected = cmd.ExecuteNonQuery();
            return intRowsAffected;
        }
    }
    
  14. VS2019からWebフォーム(Article001.aspx)のコードビハインド(Article001.aspx.cs)を開いたら、ListViewの「ListView1_PreRender()」イベントを追加します。 OnPreRenderイベントはASP.NETがListViewにデータをバインドしてブラウザにListViewの内容を表示(送信)する前に発生します。

    ここではListViewのInsertItemTemplateに定義されているUrl、Title、Category、ViewCount、DateLastViewedのTextBoxにデフォルト値(既定値)を設定しています。 ListViewに配置しているTxtBoxを見つけるにはFindControl()メソッドを使用します。 InsertItemTemplate内に配置したTextBoxを見つけるときは「ListView1.InsertItem.FindControl("UrlTextBox")」のように記述します。 FindControl()メソッドの引数にはTextBoxのIDプロパティに設定した名前を指定します。実際のデフォルト値の内容は「Live DEMO」をご覧ください。

    NOTE: 今日のシステム日付は「DateTime.Today」で取得できますがWebアプリケーションを作成するときは「DateTime.UtcNow」を使用して世界標準時間からローカル時間(日本時間)に変換します。 Webアプリを作成するときは絶対「DateTime.Today」は使わないでください。
    
    Article001.aspx.cs:
    
    protected void ListView1_PreRender(object sender, EventArgs e)
    {
        TextBox txtUrl = (TextBox)ListView1.InsertItem.FindControl("UrlTextBox");
        txtUrl.Text = "Root_Menu_AspNet_Article_Article???.aspx";
    
        TextBox txtTitle = (TextBox)ListView1.InsertItem.FindControl("TitleTextBox");
        txtTitle.Text = "ASP.NET Article ???";
    
        TextBox txtCategory = (TextBox)ListView1.InsertItem.FindControl("CategoryTextBox");
        txtCategory.Text = "AspNet";
    
        TextBox txtViewCount = (TextBox)ListView1.InsertItem.FindControl("ViewCountTextBox");
        txtViewCount.Text = "0";
    
        TextBox txtDateLastViewed = (TextBox)ListView1.InsertItem.FindControl("DateLastViewedTextBox");
        txtDateLastViewed.Text = String.Format("{0:yyyy/MM/dd}", DateTime.UtcNow.AddHours(9));
    } 
    
  15. Webフォームのコードビハインド(Article001.aspx.cs)にListViewの「ListView1_ItemDataBound()」イベントを追加します。 OnItemDataBound()イベントは、ASP.NETがListViewにデータをバインドした直後に発生します。

    ここではEditItemTemplate内に定義したDateLastViewedのTextBoxの内容を書き換えています。 StatsテーブルのDateLastViewedフィールドにはWebフォームを表示したときの日時(yyyy/mm/dd hh:mm:ss)が格納されていますが、 ここでは時刻(hh:mm:ss)の部分を削除して日付(yyyy/mm/dd)のみ表示しています。 OnItemDataBoundイベントが発生したときにカレントのアイテム(e.Item)がItemTemplate内のアイテムなのかEditItemTemplate内のアイテムなのかを識別するにはListViewのEditIndexプロパティとListViewDataItemのDataItemIndexプロパティを比較します。 カレントアイテムのインデックス番号(DataItemIndex)がEditItemTemplateのインデックス番号と一致するときのみDateLastViewのTextBoxの値を書き換えます。

    TIP:ListViewにOnPreRender()イベントとOnItemDataBound()イベントを登録したときは、OnItemBound()▶OnPreRende()の順にコントロールが渡ります。 OnPreRenderイベントには1回のみコントロールが渡りますが、OnItemBound()イベントにはListViewのItemTemplateにバインドされるレコード毎に毎回渡ります。 たとえば、AccessのStatsテーブルに10件のレコードが登録されているときは10回OnItemBoundイベントが発生します。 ListViewの[Edit]ボタンをクリックしたときEditIndexにはその行のインデックス番号(0から始まる)が設定されています。 たとえば、2行目の[Edit]ボタンをクリックしたときはEditIndexプロパティには「1」が設定されます。 ListViewの[Edit]ボタンをクリックしていないときはEditIndexプロパティには「-1」が設定されています。 ListViewDataItemのDataItemIndexプロパティには先頭0から始まるインデックス番号が常に設定されます。 したがって、EditIndexとDataItemIndexが一致する行が[Edit]ボタンをクリックした行ということになります。

    NOTE: ListViewにページング機能を追加するときは、DataItemIndexプロパティの代わりにDisplayIndexプロパティを使用します。 詳細はArticle003を参照してください。
    
    Article001.aspx.cs:
    
    protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        if (ListView1.EditIndex == (e.Item as ListViewDataItem).DataItemIndex)
        {
            TextBox txtDateLastViewed = (TextBox)e.Item.FindControl("DateLastViewedTextBox");
            txtDateLastViewed.Text = txtDateLastViewed.Text.Trim().Substring(0, 10);    // Remove Time 2021/05/23 hh:mm:dd ▶ 2021/05/23
        }
    } 
    

操作手順

  1. 新規レコードを追加するにはListViewの最終行に表示されているTextBoxにデータを入力して[Add New]ボタンをクリックします。 AccessのStatsテーブルに新規レコードを追加してListViewに表示します。 通常レコードを新規登録するときは入力データを検証してエラーがあるときはエラーメッセージを表示しますがこのサンプルでは省略しています。 入力データを検証するサンプルはArticle005のLive DEMOをご覧ください。 CategoryのTextBoxにカテゴリーを手入力する代わりにDropDownListからマウスで選択するサンプルはArticle004のLive DEMOをご覧ください。

    TIP: ブラウザに表示されているWebページのカレントの位置を保持したいときはWebフォームの@Pageディレクティブに「MaintainScrollPositionOnPostback="true"」を追加します。 これでWebページがポストバックされてもカレントの位置が保持されます。
    
    <%@ Page Language="C#" Trace="false" MaintainScrollPositionOnPostback="true" .... %>
    
  2. ListViewからレコードを削除するには該当行の[Delete]ボタンをクリックします。 これでStatsテーブルから該当レコードが削除されます。 通常レコードを削除するときは念のために本当に削除してよいか再度確認しますがこのサンプルではこの処理を省略しています。 レコードを削除するとき確認の問い合わせをするサンプルはArticle004のLive DEMOをご覧ください。 またレコードの削除処理が正常に終了したかとうかのメッセージを表示するサンプルについてはArticle006のLive DEMOをご覧ください。

  3. ListViewからレコードを編集(修正)するには該当行の[Edit]ボタンをクリックします。 [Edit]ボタンをクリックすると該当行が編集モードに切り替わるのでレコードを編集して[Update]ボタンをクリックします。 Statsテーブルのレコードが更新されてListViewに再表示されます。 レコードの編集をキャンセルしたいときは[Cancel]ボタンをクリックします。 通常レコードを更新するときは入力データを検証してエラーがあるときはエラーメッセージを表示しますがこのサンプルでは省略しています。 入力データを検証するサンプルはArticle005のLive DEMOをご覧ください。

Live DEMO

Command Url / Title Category View Count Date Last Viewed
Root_Menu_AspNet_Article_Article003.aspx
ListViewにページング機能を追加する (Article003)
AspNet 17 2021/06/07
Root_Menu_AspNet_Article_Article005.aspx
ListViewに検証コントール(Validator)を追加する (Article005)
AspNet 43 2021/06/07
Root_Menu_AspNet_Article_Article012.aspx
ListViewにCheckBoxを追加する (Article012) ★
AspNet 13 2021/06/08
Root_Menu_AspNet_Article_Article013.aspx
ListViewの複数のフィールドににフィルターを適用して表示するレコードを絞り込む (Article013) ★
AspNet 28 2021/06/08
Root_Menu_AspNet_Article_Article014.aspx
ListViewにHyperLinkを追加しさらにTextBoxにTextMode="MultiLine"を追加して入力領域の幅を節約する (Article014) ★
AspNet 17 2021/06/08
Root_Menu_AspNet_Article_Article015.aspx
Repeaterにフィルター機能を追加してレコードを絞り込む 【da.Fill(,maxRows,) Version 】 (Article015) ★
AspNet 6 2021/06/08
Root_Menu_AspNet_Article_Article016.aspx
ListViewから追加・編集・削除ボタンをクリクしたとき処理中のメッセージを表示する (Article016)
AspNet 11 2021/06/09
Root_Menu_AspNet_Article_Article017.aspx
ListViewから追加・編集・削除ボタンをクリクしたとき処理中はボタンを無効にしてダブルクリックを防止する (Article017)
AspNet 11 2021/06/08
Root_Menu_AspNet_Article_Article018.aspx
ListViewからマウスを使用して日付、数字を入力する (Article18) ★
AspNet 31 2021/06/08
Root_Menu_AspNet_Article_Article019.aspx
ListViewから入力したデータの検証をサーバー側で行う (Article019) ★
AspNet 74 2021/06/08
Root_Menu_AspNet_Article_Article020.aspx
ListViewのヘッダーにCheckBoxを追加して全てのアイテムを選択・解除できるようにする (Article020) ★
AspNet 16 2021/06/08
Root_Menu_AspNet_Article_Article021.aspx
ListViewに画像を表示する (Article021) ★
AspNet 37 2021/06/09
Root_Menu_AspNet_Article_Article022.aspx
WebページにListViewとObjectDataSourceのイベントのトレースを表示する (Article022) ★
AspNet 97 2021/06/08
Root_Menu_AspNet_Article_Article023.aspx
ListViewから入力したデータの検証を3段階に分けて行う (Article023) ★
AspNet 58 2021/06/09
Root_Menu_HtmlCss_Article_Article001.aspx
HTMLのUL/LIタグを使用して水平型のメニューを表示する (Article001) ★
HtmlCss 20 2021/06/09
Root_Menu_HtmlCss_Article_Article002.aspx
CSSを使用してアクティブなメニュー項目を緑の背景色でハイライトさせる (Article002)
HtmlCss 7 2021/06/08
Root_Menu_HtmlCss_Article_Article003.aspx
マウスをメニュー項目に移動(フォーカス)したときに赤の背景色でハイライトさせる (Article003)
HtmlCss 7 2021/06/09
Root_Menu_HtmlCss_Article_Article004.aspx
HTMLのTABLEタグをフォーマットする (Article004)
HtmlCss 135 2021/06/09
Root_Menu_HtmlCss_Article_Article005.aspx
HTMLのDIVタグにCSSを適用して画像をズームさせる [CSSでLightbox実装] (Article005)
HtmlCss 19 2021/06/09
Root_Menu_jQuery_Article_Article004.aspx
jQueryを使用して表から行の削除ボタンをクリックしたときに念にために確認するメッセージを表示する (Article004)
jQuery 10 2021/06/09
Root_Menu_jQuery_Article_Article005.aspx
jQueryを使用して表の行に表示されているCheckBoxをクリックして行を選択する (Article005)
jQuery 6 2021/06/08
Root_Menu_jQuery_Article_Article006.aspx
jQueryを使用して表のヘッダーに表示されているCheckBoxをクリックしてすべての行を選択する (Article006)
jQuery 6 2021/06/08
Root_Menu_jQuery_Article_Article007.aspx
jQueryを使用して[注文]ボタンをダブルクリック(二重注文)するのを防止する (Article007)
jQuery 14 2021/06/09
Root_Menu_jQuery_Article_Article008.aspx
JavaScript/jQueryを使用してDate型のTextBoxに今日の日付を表示する (Article008)
jQuery 40 2021/06/09
Root_Menu_LibArts_Article_Article001.aspx
人間はなぜこの世に生まれてきたのか? (Article001)
LibArts 0 2021/05/25
Root_Menu_LibArts_Article_Article002.aspx
善とは? 悪とは? (Article002)
LibArts 0 2021/05/25
Root_Menu_LibArts_Article_Article003.aspx
実在意識(顕在意識)と潜在意識の違いとは? (Article003)
LibArts 1 2021/06/15
Root_Menu_LibArts_Article_Article004.aspx
天命と運命の違いとは? (Article004)
LibArts 0 2021/05/25
Root_Menu_LibArts_Article_Article005.aspx
資本主義とは? (Article005)
LibArts 0 2021/05/25