- PR -

[VS2005 ASP.NET C♯]GridViewの動的作成テンプレートのポストバック時の値取得について

投稿者投稿内容
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2007-02-16 22:24
見落としがなければ、それで大丈夫そうなのですが。
所々、用語を正確に使われていないようなので、誤解があるかもしれません。
先に出された inputGridViewTemplate のコードも正確に何をしたいのかよく分かりません。

Page_Load 内で行っているコード、RowDataBound 内で行っているコードを見せてもらえますか?現象が発生する最低限のコードを正確にお願いします。
_________________
囚人のジレンマな日々
のぉりぃ
会議室デビュー日: 2007/02/15
投稿数: 14
投稿日時: 2007-02-16 23:31
>囚人さん
返答ありがとうございます。
Page_Loadで行っているコードを簡単に書いてます。
知りたい情報と違っていたらすみません

protected void Page_Load(object sender, System.EventArgs e)
{
// カウント数分テンプレートフィールドを作成
for (int i = 0; i < Count; i++)
{
TemplateField tFieldTest = new TemplateField();
tFieldTest.ItemTemplate = new inputGridViewTemplate(i);
inputGridView.Columns.Add(tFieldProject);
}

// データソース設定
inputGridView.DataSource = [データビュー];
// 入力情報のバインド実行
inputGridView.DataBind();

//-------------------------------------------------------------------------------------------------------------:
/// <summary>
/// グリッドビューにバウンドされた後の動作(セル色設定) ←RowDataBoundイベント
/// </summary>
//-------------------------------------------------------------------------------------------------------------:
// 一行バインドが終わる毎に発生(発生前にTemplateClassのDataBinderイベントでコントロール生成)
protected void inputGridView_DataBound(Object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int Count = e.Row.Cells.Count - 5;
for (int i = 0; i < Count; i++)
{
System.Web.UI.WebControls.TextBox hoge = (System.Web.UI.WebControls.TextBox)e.Row.FindControl("test" + i);
// 値が入っていない場合
if (hoge.Text == "")
{
hoge.BackColor = Color.FromName("#ff88aa");
}
}
}
}
}
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-02-17 00:42
引用:
今の作りですと、バインドを行わなとテキストボックス(コントロール)が作成されない状況です。
そこで、PostBack時にもデータバインドをしてテンプレートフィールドを作成したのですが、その場合はDBから取得したデータが入ってしまいます。

なんとなくわかってきました。バインドしないとTextBoxが作られない、
けどバインドするとDBの値とってきちゃうからユーザーの入力が消えちゃう、ってことですね。

引用:
ただ、実際の行の中のコントロールの追加はDataBind時に行っているので難しいです。
Bindなしでコントロールを配置できれば問題ないんでしょうが。。。

RowCreatedかなんかでCellもTextBoxも作ればいいんじゃないでしょうか。
そもそも独自テンプレートを作る理由がわかりません。

[ メッセージ編集済み 編集者: べる 編集日時 2007-02-17 00:46 ]
のぉりぃ
会議室デビュー日: 2007/02/15
投稿数: 14
投稿日時: 2007-02-18 00:57
>べるさん
返答ありがとうございます。

たしかに、RowCreatedでテキストボックスを作ればうまくいきそうですね。
現に、ヘッダーはRowCreatedで作ってますし。
しかし、RowCreatedでテキストボックスを行に追加という処理はできるのでしょうか?
少しやってみたのですが、Cellの追加はできますがTextBoxの追加方法がいまいちよくわかりません。
また、AutoGenerateColumsをFalseに設定している場合、全項目をRowCreatedで行ったらGridView自体が表示されなくなりました。

なかなか、うまくいきません。
改めて自分の技術のなさを痛感しました。
Access
ぬし
会議室デビュー日: 2002/04/08
投稿数: 829
投稿日時: 2007-02-18 05:55
ページライフサイクルをもう一度確認してください。

GridViewにTemplateField(TextBox)を追加してポストバックさせると、
TextBoxに入力したデータは、(4)のLoadPostBackDataで復元されます。

したがって、GridViewにTemplateFieldを追加する処理をPreInit、OnInitで
行う必要があります。

(5)のPage_LoadでTemplateFieldを追加するとLoadPostBackDataの後ですから
TextBoxの内容が復元されないのが理解できると思うのですが・・・

工夫次第でPreInitでTemplateFieldを追加できるのでは?

サンプルを作成しましたので参考にしてください。

GridViewにTemplateField(TextBox)をダイナミックに追加
http://www.gxbrbwda.sv02.fsdotnet.net/Goto.aspx?id=070218VB-1



Page Life Cycle:
(1)PreInit
(2)OnInit
(3)LoadViewState(IsPostBack=true)
(4)LoadPostBackData(IPostBackDataHandler)
(5)Page_Load
(6)Control Event Handlers
(7)PreRender
(8)SaveViewState 
(9)Render
(10)Unload
_________________
ASP.NET+Ajaxサンプル集 | JavaScript+Ajaxサンプル集
のぉりぃ
会議室デビュー日: 2007/02/15
投稿数: 14
投稿日時: 2007-02-18 13:39
>Accessさん
返答ありがとうございます。
Accessさんのおっしゃるように(3)までにテキストボックスを作成しておかないといけないとうことがわかりました。
もし、差し支えがなければTemplateFieldクラスのソースを見せていただけないでしょうか?どのタイミングでテキストボックスを追加しているか知りたいためです。
Initで動的に作成する数はなんとか取得できそうです。
わざわざサンプルまで作ってもらってすみません。
べる
ぬし
会議室デビュー日: 2003/09/20
投稿数: 1093
投稿日時: 2007-02-19 01:25
引用:
たしかに、RowCreatedでテキストボックスを作ればうまくいきそうですね。
現に、ヘッダーはRowCreatedで作ってますし。
しかし、RowCreatedでテキストボックスを行に追加という処理はできるのでしょうか?
少しやってみたのですが、Cellの追加はできますがTextBoxの追加方法がいまいちよくわかりません。

Cellが追加できてるならば Cell1.Controls.Add(TextBox1) という風にすればいいだけです。

ただ、せっかくテンプレートクラスまで作っているのならAccessさんのアプローチで進めたほうが
スマートだと思います。

引用:
もし、差し支えがなければTemplateFieldクラスのソースを見せていただけないでしょうか?どのタイミングでテキストボックスを追加しているか知りたいためです。

TemplateFieldは.NETにもともとあるものです。見たいのはMyTemplate2のほうでは?

バインドしないとTextBoxが生成されない、というのが原因なのですからバインドしないときでも
テンプレートの実体が生成された(言い方あってるかな。。)タイミング、つまり
InstantiateInでTextBoxを作ってあげればいいのです。TextBoxのTextプロパティを設定するのだけ
test_DataBinding で行い、他は InstantiateIn で行えばよいはずです。
Access
ぬし
会議室デビュー日: 2002/04/08
投稿数: 829
投稿日時: 2007-02-19 06:18
引用:

もし、差し支えがなければTemplateFieldクラスのソースを見せていただけないでしょうか?どのタイミングでテキストボックスを追加しているか知りたいためです。


MyTemplate2のソースコードです。
参考になれば幸いです。

コード:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public class MyTemplate2 : ITemplate
{
  private string ctrlid;
  private string colname;

  public MyTemplate2(string ctrlid, string colname)
  {
    this.ctrlid = ctrlid;
    this.colname = colname;
  }

  public void InstantiateIn(Control container)
  {
    TextBox tb = new TextBox();
    tb.ID = ctrlid;
    tb.DataBinding += new EventHandler(this.OnDataBinding);
    container.Controls.Add(tb);
  }

  public void OnDataBinding(object sender, EventArgs e)
  {
    TextBox tb = (TextBox)sender;
    GridViewRow container = (GridViewRow)tb.NamingContainer;
    tb.Text = ((DataRowView)container.DataItem)[colname].ToString();
  }
}



_________________
ASP.NET+Ajaxサンプル集 | JavaScript+Ajaxサンプル集

スキルアップ/キャリアアップ(JOB@IT)