- - PR -
動的に追加したテンプレート列にボタンイベントを追加したい
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2006-11-01 14:11
いつもお世話になります。現在vb.net(vs2003)を用いて開発を行なっています。
私が困っているのはテンプレート列に動的にテキストやボタンを追加して表形式の画面を作ろうと考えています。(縦・横のカラム数は決まっていない) http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2627&forum=7&4 や http://www.microsoft.com/japan/msdn/vs/webapplication/vbtchCreatingWebServerControlTemplatesProgrammatically.aspx#vbtchcreatingwebservercontroltemplatesprogrammaticallyanchor3 を参考にして動的にテンプレート列を追加してテキストにデータバインドしてボタンを表示するところまではできました。 しかしボタンのイベントをどうやって発生させたらいいのかが分かりません。 ボタンを追加する際に、次のようにAddHandlerを入れてはいるのですがイベントに入ってくれません。 AddHandler buttonAdd.Click, AddressOf TemplateControl_Click 動的に作成したテンプレートのボタンイベントを実行する方法を教えてください。 |
|
投稿日時: 2006-11-01 22:17
Web アプリですよね?
まず、Page.Load イベントが発生しているか、確認してください。 そして、Page.Load イベントの終了直前に、動的に追加しているはずのテキストやボタンが存在しているか、確認してください。 Web アプリは、Win アプリと違って、サーバ コードが走るときには毎回新しいオブジェクトが作成されます。以前あったからといって、今回もあるとは限りません。 _________________ |
|
投稿日時: 2006-11-02 11:33
jittaさん返信ありがとうございます。
申し訳ありません。記述が足りませんでした。webアプリです。 page.loadイベントは発生しています。またテキストやボタンも作成されています。 ただボタンに設定したはずのCommandNameが設定されていません。 AddHandlerがうまいこといかないのでItemCommandイベントでCommandNameごとに処理をしようとしているのですが・・・。 動的に作成したテンプレートのボタンイベントってとれるのでしょうか? ほとほと困っています。 以上 よろしくお願いします。 |
|
投稿日時: 2006-11-02 12:11
「動的にテンプレート列を追加」をPage_LoadではなくPage_Initで行うとよいかも。[ メッセージ編集済み 編集者: todo 編集日時 2006-11-02 16:20 ] |
|
投稿日時: 2006-11-02 16:31
動的に追加したボタンのonClickイベントで、動的に追加していないボタンを押下するJavaScriptを記述する方法は?
必要ならばパラメタもhidden項目にセットするようにしては? |
|
投稿日時: 2006-11-02 21:52
Web アプリでは、サーバ コードが実行されるごとに、毎回オブジェクトが作られます。
このため、AddHandler をしても、次にサーバ コードが実行されるときには、そのオブジェクトはありません。 で、どうするかというと、CommandName です。これを設定しておくと、Itemcommand イベントが発生します。このイベントで、CommandName を見て、処理を振り分けます。 ……ここまでは ok ですね。 で、次。Web アプリケーションでは、サーバ コードが実行されるごとに、毎回オブジェクトが作られます。 何度も繰り返すのは、とても重要で、絶対に憶えておいて欲しいことだからです。 毎回新しく作られるなら、「状態が変わった」というイベントは発生させられません。これは、分かりますか?ボタンのクリックも、ボタンが「押されていない状態」から、「押されている状態」(そして、離された状態)へ変化したから発生するものです。 このため、「前回のサーバ コード実行時の状態」を、どこかに保存しておく必要があります。その一つが ViewState です。 端折りますが、クライアントからの要求を受け付けると、ViewState からコントロール情報を復元し、「前回のサーバ コード実行時の状態」を復元した上で、Page.Load イベントが発生します。ボタン クリックなどのイベントは、この後に発生します。 したがって、Page.Load で、「前回の…状態」を潰してしまうと、イベントを発生させるための情報も無くなってしまい、イベントが発生しなくなります。(todoさんのアドバイス) ViewState が無効になっていませんか?DataGrid の ViewState を有効にしてみてください。 Page.Load の中で DataBind を行っていませんか?その部分を IsPostBack を見て、True ならば通らないようにしてみてください。 _________________ |
|
投稿日時: 2006-11-06 10:51
Jittaさん、ぜうすさん、todoさん返信ありがとうございます。また返信が遅れて申し訳ありません。
jittaさん>ViewState が無効になっていませんか? はい。無効になっていません。 jittaさん>Page.Load の中で DataBind を行っていませんか?その部分を IsPostBack を見て、True ならば通らないようにしてみてください そのようになっているとは思うのですが・・・。 長くなって申し訳ありませんがテスト的に作成したソースを転記します。左に列を追加ボタンを押しても DataGrid1_ItemCommandイベントが発生しません。悪い箇所を指摘して頂けると大変ありがたいのですが・・・。以上 よろしくお願い致します。 ---------------------------------------------------------------- ☆webフォーム Public Class WebForm1 Inherits System.Web.UI.Page Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Not IsPostBack = True Then 'テンプレート列1 Dim tc1 As New TemplateColumn tc1.HeaderTemplate = New _ DataGridTemplate(ListItemType.Header, "Column1") tc1.ItemTemplate = New DataGridTemplate(ListItemType.Item, "Column1") tc1.EditItemTemplate = New _ DataGridTemplate(ListItemType.EditItem, "Column1") tc1.FooterTemplate = New _ DataGridTemplate(ListItemType.Footer, "Column1") DataGrid1.Columns.Add(tc1) 'テンプレート列2 Dim tc2 As New TemplateColumn tc2.HeaderTemplate = New _ DataGridTemplate(ListItemType.Header, "Column2") tc2.ItemTemplate = New DataGridTemplate(ListItemType.Item, "Column2") tc2.EditItemTemplate = New _ DataGridTemplate(ListItemType.EditItem, "Column2") tc2.FooterTemplate = New _ DataGridTemplate(ListItemType.Footer, "Column2") DataGrid1.Columns.Add(tc2) Dim TempHeader As New TemplateHeadDb TempHeader.GetTemplateHeader("42", Me.DataSet1) 'ここでデータをデータを取得 ViewState("DataSet") = Me.DataSet1 DataGrid1.DataSource = Me.DataSet1 DataGrid1.DataBind() End If End Sub ↓☆ここに入らない Private Sub DataGrid1_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles DataGrid1.ItemCommand End Sub End Class ---------------------------------------------------------------- ☆テンプレートクラス Public Class DataGridTemplate Implements ITemplate Dim templateType As ListItemType Dim columnName As String Sub New(ByVal type As ListItemType, ByVal ColName As String) templateType = type columnName = ColName End Sub Sub InstantiateIn(ByVal container As Control) Implements ITemplate.InstantiateIn Dim lc As New Literal Select Case templateType Case ListItemType.Header ' ヘッダ Dim PlaceHolder As PlaceHolder = New PlaceHolder lc.Text = "<B>" & columnName & "</B>" PlaceHolder.Controls.Add(lc) container.Controls.Add(PlaceHolder) Case ListItemType.Item ' アイテム表示 Dim PlaceHolder As PlaceHolder = New PlaceHolder Dim buttonAdd As New System.Web.UI.WebControls.Button buttonAdd.Text = "左に列を追加" buttonAdd.CommandName = "NextMeisai" ←☆ここでCommandNameをセットしている PlaceHolder.Controls.Add(buttonAdd) '追加ボタン lc.Text = columnName PlaceHolder.Controls.Add(lc) container.Controls.Add(PlaceHolder) Case ListItemType.EditItem ' 編集 Dim tb As New TextBox tb.Text = columnName container.Controls.Add(tb) Case ListItemType.Footer ' フッタ Dim tb As New TextBox tb.Text = "" container.Controls.Add(tb) End Select End Sub Private Sub TemplateControl_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) Dim lc As Literal lc = CType(sender, Literal) Dim container As RepeaterItem container = CType(lc.NamingContainer, RepeaterItem) lc.Text &= DataBinder.Eval(container.DataItem, "CategoryName") lc.Text &= "</TD></TR>" End Sub End Class |
1