C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[11]: GridViewへTemplateを動的に作成


(過去ログ 76 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■45217 / inTopicNo.1)  GridViewへTemplateを動的に作成
  
□投稿者/ T_A~K_A (32回)-(2010/01/06(Wed) 11:06:24)

分類:[ASP.NET (VB)] 

こんばんは。
T_A~K_Aと申します。

現在、ASP.NETにてaspx側に列定義をせずにプログラムから動的に列作成しようと
しております。

■googleにて調査した結果です。
http://support.microsoft.com/kb/310898/ja
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2627&forum=7

手法としては、ある列を作成するにあたりクラスをNewします。
バインド時にImplements ITemplate.InstantiateInというメソッドが自動的に
呼び出されるようです。

似たようなもの作成して実験しているのですが、
どうも自動的にInstantiateInメソッドが呼び出されません。

私、個人的にImplementsの意味がよく分かっていないのも一つの原因です。
調べましたがざっくりとした事しか記載されていないので今一理解できていません。


どなたか、ご存知の方いらっしゃいましたらご教授願います。

引用返信 編集キー/
■45219 / inTopicNo.2)  Re[1]: GridViewへTemplateを動的に作成
□投稿者/ もりお (154回)-(2010/01/06(Wed) 13:24:20)
No45217 (T_A~K_A さん) に返信
> こんばんは。

夜な環境にいらっしゃる?

> 似たようなもの作成して実験しているのですが、
> どうも自動的にInstantiateInメソッドが呼び出されません。

どのように記述されて、呼び出されないことをどのように確認されたのか
お教えいただけるとありがたいです。

新しい TemplateField 列を追加するだけであればこんな感じで出来ました。
GridView のデータソースには SqlDataSource を利用しています。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim newColumn As New TemplateField()
    newColumn.ItemTemplate = New TestItemTemplate()
    GridView1.Columns.Add(newColumn)
End Sub

Class TestItemTemplate
    Implements ITemplate

    Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) _
            Implements System.Web.UI.ITemplate.InstantiateIn
        container.Controls.Add(New LiteralControl("追加しましたよー"))
    End Sub
End Class

引用返信 編集キー/
■45220 / inTopicNo.3)  Re[2]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (33回)-(2010/01/06(Wed) 14:25:56)
もりおさん返信ありがとう御座います。

こんにちはでしたorz
確認したソースです。C#ですが・・・。

using System;
using System.Data;
using System.Configuration;
using System.Collections;
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;

namespace test2
{
// ITemplateを継承したCustomTemplateクラス
public class CustomTemplate : ITemplate
{
public void InstantiateIn(Control container)
{
// ボタンとテキストを追加
container.Controls.Add(new Button());
container.Controls.Add(new TextBox());
}
}

public partial class _Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!this.IsCallback) {
// GridViewにテンプレート列を追加する。
TemplateField template = new TemplateField();
template.ItemTemplate = new CustomTemplate();
this.GridView1.Columns.Add(template); // GridViewにデータを追加する
string[] list = { "Sunday", "Monday", "Tuesday" };
this.GridView1.DataSource = list;
this.GridView1.DataBind();
}
}

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
if (e.Row.RowType == DataControlRowType.DataRow) {
Button button = (Button)e.Row.Cells[0].Controls[0];
button.Text = e.Row.DataItem.ToString(); // ボタンの表示名を変更
}
}
}
}

上記ソースコードでバインド時に、ITemplateを継承したクラスCustomTemplateのメソッドInstantiateInが
関数コールされます。恐らく似たような感じだと思います。

ただこのコードを、本番のソースコードに埋め込んでみてもメソッドInstantiateInが関数コールされないのです。
今色々やっていますが・・・サンプルだと単純なんですけどねぇ・・・機能を盛り込んでいる物に対して追加して
いるのでどこが悪さしているのか調査中って感じなのです。

引用返信 編集キー/
■45222 / inTopicNo.4)  Re[3]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (35回)-(2010/01/06(Wed) 15:09:43)
こんにちは。
T_A~K_Aです。

とりあえず、原因が分かりました。
1.ページロード(1回目)の時にテンプレート列を追加(他にBoundFieldも4列追加)
2.「検索」ボタンを押下(2回目)してDataTableへデータを追加してバインド
3.1にて追加したTemplateField列の定義が消える。但し、BoundFieldの残っている。
でした。

回避方法は、まだ分かっていません。

引用返信 編集キー/
■45223 / inTopicNo.5)  Re[4]: GridViewへTemplateを動的に作成
□投稿者/ いしだ (219回)-(2010/01/06(Wed) 15:18:17)
2010/01/06(Wed) 15:42:15 編集(投稿者)

> 1.ページロード(1回目)の時にテンプレート列を追加(他にBoundFieldも4列追加)

if (!this.IsCallback) {

この中で追加しているから、ポストバック発生時に動的生成されたコントロールが
消えるのではないでしょうか。

[編集]
あれ?CallBack?PostBackじゃないんだ。。。
失礼しました。

引用返信 編集キー/
■45224 / inTopicNo.6)  Re[5]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (36回)-(2010/01/06(Wed) 16:03:23)
いしださん返信ありがとう御座います。

> この中で追加しているから、ポストバック発生時に動的生成されたコントロールが
> 消えるのではないでしょうか。
下記コードで動的に生成しています。

If False = Me.IsPostBack Then
★1回目のPostBackここで動的に生成
else
★2回目以降のPostBack
endif

仮にそうであってもBoundFieldは消えません。残っています。
TemplateFieldが消えてしまいます。
MSの仕様なんでしょうかねぇ〜。
まだ、回避方法は分かっていません。

引用返信 編集キー/
■45226 / inTopicNo.7)  Re[6]: GridViewへTemplateを動的に作成
□投稿者/ いしだ (220回)-(2010/01/06(Wed) 16:39:47)
> If False = Me.IsPostBack Then
> ★1回目のPostBackここで動的に生成
> else
> ★2回目以降のPostBack
> endif
>

動的に作成したコントロールですから、最初だけ作成しても駄目ですよ。

引用返信 編集キー/
■45229 / inTopicNo.8)  Re[7]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (37回)-(2010/01/06(Wed) 17:11:20)
いしださん返信ありがとう御座います。

> 動的に作成したコントロールですから、最初だけ作成しても駄目ですよ。
だとすると動的に作成したBoundFieldは、残っている事が疑問です。
全て消えてしまうのであれば理解できますが・・・。

2回目のPostBack時にGridViewのカラムの数を取得したら6個ありました。(初回に動的に6個追加しています)
つまり、GridViewは追加した列数は分かっている?という事になります。
但し、TemplateFieldの情報は消えてしまっている状態です。

従って、同様に初回時に追加したカラムを再度追加すると6個アペンドされてしまいます。
カラムの数が12個になってしまいます。実際にブラウザに表示されましたが、やはり列が増えてしまいました。

ですので、以降GridViewのカラムをクリアしてから動的に再度作成しバインドさせてみました。
一応期待動作するようになりました。

解決済み
引用返信 編集キー/
■45231 / inTopicNo.9)  Re[8]: GridViewへTemplateを動的に作成
□投稿者/ もりお (155回)-(2010/01/06(Wed) 17:20:19)
2010/01/06(Wed) 17:24:19 編集(投稿者)
No45229 (T_A~K_A さん) に返信
> だとすると動的に作成したBoundFieldは、残っている事が疑問です。

No45224 への返答になっていますがご容赦ください。

> 仮にそうであってもBoundFieldは消えません。残っています。
> TemplateFieldが消えてしまいます。

ポストバック発生時に動的に生成されたコントロールが消えてしまうと
仮定するならば同じように動的に生成した BoundField も消えるはずなので
仮定は間違っているという意味でしょうか。
この論理を保証するには TemplateField と BoundField は PostBack 時に同
じ挙動を示すという前提が必要になります。
ところが、この前提の部分が違う可能性があります。
BoundField と TemplateField はどちらも IStateManager インターフェース
を実装した DataControlField クラスを継承したものですが TemplateField
の ItemTemplate には ITemplate インターフェースを実装しただけのクラス
のインスタンスをセットしています。
つまり、BoundField は ViewState から復元されるけれども TemplateField
の ItemTemplate は復元されないため PostBack 時に消えてしまうという可能
性が考えられます。

解決済み
引用返信 編集キー/
■45240 / inTopicNo.10)  Re[9]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (38回)-(2010/01/07(Thu) 10:08:17)
もりおさん返信ありがとう御座います。

> ポストバック発生時に動的に生成されたコントロールが消えてしまうと
> 仮定するならば同じように動的に生成した BoundField も消えるはずなので
> 仮定は間違っているという意味でしょうか。
間違っているという意味ではありません。
なぜ?だろうという事です。

> この論理を保証するには TemplateField と BoundField は PostBack 時に同
> じ挙動を示すという前提が必要になります。
> ところが、この前提の部分が違う可能性があります。
> BoundField と TemplateField はどちらも IStateManager インターフェース
> を実装した DataControlField クラスを継承したものですが TemplateField
> の ItemTemplate には ITemplate インターフェースを実装しただけのクラス
> のインスタンスをセットしています。
> つまり、BoundField は ViewState から復元されるけれども TemplateField
> の ItemTemplate は復元されないため PostBack 時に消えてしまうという可能
> 性が考えられます。
可能性として有り得るのであれば、疑問は解けます。
わざわざ、ありがとう御座います。

解決済み
引用返信 編集キー/
■45254 / inTopicNo.11)  Re[10]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (39回)-(2010/01/07(Thu) 15:26:30)
こんにちは。T_A~K_Aです。

何とか TemplateField と BoundField を動的に作成する事が出来ました。
ただ、動的に作成する場合はPage_Loadではなく、Initで作成しておく必要があるようです。

■参考URL
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=36752&forum=7

でないと動的に作成した TemplateFieldのCheckBox に対してユーザがチェックした情報を
次回のPost時に、FindControlで取得できない問題があります。
とりあえず、これは回避できました。

ただ、特定の行に対して編集モードにするという事がやりたいのですが・・・。
具体的には、チェックされている行を.Net標準の編集モードを使用したいのです。

Me.GVDetailLeft.EditIndex = 2 ' 編集モードにした行をEditIndexへ代入
Me.GVDetailLeft.DataSource = Session("Left")
Me.GVDetailLeft.DataBind()

Me.GVDetailRight.EditIndex = 2 ' 編集モードにした行をEditIndexへ代入
Me.GVDetailRight.DataSource = Session("Right")
Me.GVDetailRight.DataBind()

インプリメントした独自のTemplateFieldにて自動的に判断させる事はできないのでしょうか?
バインド時にInstantiateIn(ByVal container As Control) Implements System.Web.UI.ITemplate.InstantiateInが
行単位にコールされるので・・・。

どなたかご存知でしたらご教授願います。



引用返信 編集キー/
■45264 / inTopicNo.12)  Re[11]: GridViewへTemplateを動的に作成
□投稿者/ T_A~K_A (42回)-(2010/01/07(Thu) 16:58:47)
T_A~K_Aです。

自己解決致しました。

Dim tmpField As TemplateField

tmpField.ItemTemplate = New MyTemplateField
tmpField.EditItemTemplate= New MyTemplateField ★

★印のコードを追加したところ、対象行が編集モードへ変換されました。
EditItemTemplateに対してインプリメントしていませんでしたorz

お騒がせしました。皆さんありがとう御座います。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -