このサンプルでは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を参照してください。
-
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;
}
-
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>
-
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>
-
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>
-
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>
-
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>
-
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);
}
-
ツールボックスから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>
-
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>
-
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;
}
}
-
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;
}
}
-
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;
}
}
-
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;
}
}
-
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));
}
-
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
}
}