dポイントプレゼントキャンペーン実施中!

GridViewやListViewなどに動的にデータを追加していきたいので、
DataTableを使おうと思いました。

下記、(1)のようにPageLoadイベントで1行追加することはできたのですが、
ボタンを押すごとに、1行ずつ追加していきたいので(2)のように修正したのですが、
ボタンを押したときのポストバックで、DataSetもDataTableもnullになってしまい、
行の追加ができません。
ボタンを押すごとにどんどん行を追加していきたいのですが、このような場合は
どのようにDataSetもDataTableを保持しておけば良いのでしょうか。

(1)
public partial class WebForm1 : System.Web.UI.Page
{

int count = 0;

protected void Page_Load(object sender, EventArgs e)
{

if (!IsPostBack)
{

DataSet dS = new DataSet("dS");
DataTable dT = new DataTable("dT");

// データテーブル カラム作成
dT.Columns.Add("no", typeof(int));
dT.Columns.Add("name", typeof(string));
dT.Columns.Add("kind", typeof(string));
dT.Columns.Add("time", typeof(int));
dS.Tables.Add(dT);

DataRow dR = dT.NewRow();
dR["no"] = count;
dR["name"] = count.ToString();
dR["kind"] = count.ToString();
dR["time"] = count;
dT.Rows.Add(dR);

// リストビュー データソース選択
ListView2.DataSource = dS;
ListView2.DataBind();

}

}
}


(2)
public partial class WebForm2 : System.Web.UI.Page
{
int count = 0;
DataSet dS;
DataTable dT;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{

dS = new DataSet("dS");
dT = new DataTable("dT");

// データテーブル カラム作成
dT.Columns.Add("no", typeof(int));
dT.Columns.Add("name", typeof(string));
dT.Columns.Add("kind", typeof(string));
dT.Columns.Add("time", typeof(int));
dS.Tables.Add(dT);

}
}

protected void Button1_Click(object sender, EventArgs e)
{
count = count + 1;

DataRow dR = dT.NewRow();
dR["no"] = count;
dR["name"] = count.ToString();
dR["kind"] = count.ToString();
dR["time"] = count;
dT.Rows.Add(dR);

// リストビュー データソース選択
ListView2.DataSource = dS;
ListView2.DataBind();

}
}

A 回答 (3件)

#1です。



自分は DataTable を使う場合、TableAdapter を使った「強い型つき」DataTable しか使わないので、そもそも、単なる DataTable の入れ物にすぎない DataSet を使う習慣がないのですが、

var sampleDataTable = new SampleTableAdapter.Get_All();
ListView2.DataSource = sampleDataTable;

普通は、DataTable をバインドするのと違いますか?
DataSet をバインドすると、たしかデフォルトで DataSet 中に定義された先頭の DataTable がバインドされるので、ご提示のケースですと、 dS にdT が収められていないだけのような気がするのですが。
    • good
    • 1
この回答へのお礼

丁寧に教えて頂きありがとうございます。
無事、解決致しました。

お礼日時:2014/02/16 10:44

ポストバック時に ListView.DataSource はキャッシュされるので、



protected void Button1_Click(object sender, EventArgs e)
{
DataTable dT = (DataTable)ListView2.DataSource;
    • good
    • 1

データ更新機能を使わないのであれば、GridViewやListViewのDataSourceは単にIEnumerableを実装していればOKなわけで、DataSetやDataTableのような「無駄に重い」クラスを使うのは感心しません。


エンティティクラスの配列かリスト、コレクションなどを使う事をおすすめします。

それはおいておくとして、

ASP.NET的な方法であれば、初期表示後にその時点でのデータを Session に保存し、PostBackのたびにその値を呼出しで再生し、DBから取得した値を追加して画面表示後にそのデータをSessionに保存……という処理を繰り返します。

【初期表示】
新しいDataTableのインスタンスを作成
【ポストバック時】
Session["binddata"]からDataTableを取得
【共通】
DBからの取得分をDataTableに追加
DataBind()
Session["binddata"]としてDataTableを保存

Ajaxを自由に使えるのであれば、こういう方法は必要ないですが。。

この回答への補足

教えて頂いたSessionにDataTableを格納し、
ポストバック時にSessionから復元する方法で
試行錯誤しているのですが、Button1_ClickのListView2.DataBind()で
IListSourceにデータソースがありませんと
エラーになってしまいます。

下記のような書き方で、Sessionへの格納、復元を試みているのですが、
使い方としておかしいでしょうか。
不具合点をご指摘頂けると嬉しいです



DataSet ds;
DataTable dt;

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["cnt"] = 0;

ds = new DataSet("ds");
dt = new DataTable("dT");

// データテーブル カラム作成
dt.Columns.Add("no", typeof(int));
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("kind", typeof(string));
dt.Columns.Add("time", typeof(int));
ds.Tables.Add(dt);

DataRow dR = dt.NewRow();
dR["no"] = (int)Session["cnt"];
dR["name"] = Session["cnt"].ToString();
dR["kind"] = Session["cnt"].ToString();
dR["time"] = (int)Session["cnt"];
dt.Rows.Add(dR);

// リストビュー データソース選択
ListView2.DataSource = ds;
ListView2.DataBind();

//セッションにデータテーブルを格納
Session["myTable"] = dt;

}
else
{

ds = new DataSet("ds");
dt = new DataTable("dT");

//テータテーブルをセッションから復元
dt = (DataTable)Session["myTable"];


}
}

protected void Button1_Click(object sender, EventArgs e)
{
Session["cnt"] = int.Parse(this.Session["cnt"].ToString()) + 1;

DataRow dR = dt.NewRow();
dR["no"] = (int)Session["cnt"];
dR["name"] = Session["cnt"].ToString();
dR["kind"] = Session["cnt"].ToString();
dR["time"] = (int)Session["cnt"];
dt.Rows.Add(dR);

Session["myTable"] = dt;

// リストビュー データソース選択
ListView2.DataSource = ds;
ListView2.DataBind();

}

補足日時:2014/02/15 09:34
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています