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

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

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

Re[6]: 動的に追加したユーザーコントロールのイベントが取得できない


(過去ログ 170 を表示中)

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

■97847 / inTopicNo.1)  動的に追加したユーザーコントロールのイベントが取得できない
  
□投稿者/ emi (1回)-(2021/07/28(Wed) 15:45:41)

分類:[.NET 全般] 

開発環境:VisualStudio2019 targetFramework="4.8"
開発言語:VB.net HTML5
ブラウザ:IE Windows 10 バージョン 21H1

メインページ上の条件追加ボタン押下時にユーザーコントロールを動的に追加、
ユーザーコントロール内の条件削除ボタン押下で当該ユーザーコントロールを削除しようとしています。

ユーザーコントロールを動的に追加する処理は期待通りに動作し、PostBack時の入力値の保持も出来ています。
しかし、条件削除ボタン押下時の処理がうまくいきません。
ネットの情報をもとに試行錯誤してみましたが、先ず、onClickイベントが取得できません。
何がいけないのか、ご教授頂けませんでしょうか。宜しくお願い致します。


■メインページ
--(HTML)
<asp:button id="btnAddJyoken" runat="server" text="条件追加" />
<asp:PlaceHolder id="PlaceHolder1" runat="server"/>


--(VB)
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim arrUc As New List(Of UserControl)
    Dim uc As UserControl = CType(Page.LoadControl("../Uc/UserControl.ascx"), UserControl)

    If Not IsPostBack Then
        '【条件】最初の1つを作成
        Me.PlaceHolder1.Controls.Add(uc)
        arrUc.Add(uc)
        AddHandler uc.UserControlButtonClicked, AddressOf UserControl_UserControlButtonClicked
        Session("DynamicControls") = arrUc
    Else
        If Session("DynamicControls") IsNot Nothing Then
            Dim i As Integer
            arrUc = CType(Session("DynamicControls"), List(Of UserControl))

            For i = 0 To arrUc.Count - 1
                uc = arrUc(i)
                Me.PlaceHolder1.Controls.Add(uc)
            Next i
        End If
    End If
End Sub

Private Sub btnAddJyoken_Click(sender As Object, e As EventArgs) Handles btnAddJyoken.Click

    Dim arrUc As New List(Of UserControl)
    Dim uc As UserControl = CType(Page.LoadControl("../Uc/UserControl.ascx"), UserControl)

    Me.PlaceHolder1.Controls.Add(uc)

    For Each uc In Me.PlaceHolder1.Controls
        arrUc.Add(uc)
        AddHandler uc.UserControlButtonClicked, AddressOf UserControl_UserControlButtonClicked
    Next uc

    Session("DynamicControls") = arrUc
End Sub

Private Sub UserControl_UserControlButtonClicked(ByVal sender As Object, ByVal e As System.EventArgs)
    Dim i As Integer = 0		←ブレークポイントを設定しても止まらない
End Sub


■ユーザーコントロール
--(HTML)
<asp:button id="btnDelJyoken" runat="server" text="条件削除" />


--(VB)
Public Event UserControlButtonClicked As EventHandler

Protected Sub btnDelJyoken_Click(sender As Object, e As EventArgs) Handles btnDelJyoken.Click
    RaiseEvent UserControlButtonClicked(Me, e)		←ブレークポイントを設定しても止まらない
End Sub

引用返信 編集キー/
■97848 / inTopicNo.2)  Re[1]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ WebSurfer (2303回)-(2021/07/28(Wed) 16:57:22)
No97847 (emi さん) に返信

> ユーザーコントロールを動的に追加する処理は期待通りに動作し、PostBack時の入力値の保持も出来ています。

PostBack と書いてあるということは ASP.NET Web Forms アプリの話ですかね。

コードは見てないのでハズレかもしれませんが、よくある話として、動的に追加したコントロール
は PostBack の際にも動的に追加する必要があるのですが、それがされてないということではない
ですか?

そのあたりを調べてみてはいかがですか。
引用返信 編集キー/
■97849 / inTopicNo.3)  Re[2]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ emi (3回)-(2021/07/28(Wed) 17:05:45)
No97848 (WebSurfer さん) に返信
> ■No97847 (emi さん) に返信
>
>>ユーザーコントロールを動的に追加する処理は期待通りに動作し、PostBack時の入力値の保持も出来ています。
>
> PostBack と書いてあるということは ASP.NET Web Forms アプリの話ですかね。
>
> コードは見てないのでハズレかもしれませんが、よくある話として、動的に追加したコントロール
> は PostBack の際にも動的に追加する必要があるのですが、それがされてないということではない
> ですか?
>
> そのあたりを調べてみてはいかがですか。


返信ありがとうございます。
はい、WEBフォームです。
「PostBack の際にも動的に追加」はしていて、想定通りにユーザーコントロールの追加と値の保持は出来ています。
引用返信 編集キー/
■97850 / inTopicNo.4)  Re[3]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ PATIO (9回)-(2021/07/28(Wed) 17:17:48)
2021/07/28(Wed) 17:20:40 編集(投稿者)

No97849 (emi さん) に返信
> ■No97848 (WebSurfer さん) に返信
>>■No97847 (emi さん) に返信
>>
> >>ユーザーコントロールを動的に追加する処理は期待通りに動作し、PostBack時の入力値の保持も出来ています。
>>
>>PostBack と書いてあるということは ASP.NET Web Forms アプリの話ですかね。
>>
>>コードは見てないのでハズレかもしれませんが、よくある話として、動的に追加したコントロール
>>は PostBack の際にも動的に追加する必要があるのですが、それがされてないということではない
>>ですか?
>>
>>そのあたりを調べてみてはいかがですか。
>
>
> 返信ありがとうございます。
> はい、WEBフォームです。
> 「PostBack の際にも動的に追加」はしていて、想定通りにユーザーコントロールの追加と値の保持は出来ています。

Webフォームはやった事が無いので推測になりますが、
PostBackの際は、AddHandlerはしなくても良いのでしょうか?
パッと見てコード上の違いはその部分だけのように見えます。
Webフォームの場合、イベントとハンドラのテーブルが毎回破棄されて作り直されるのであれば、毎回必要になるような気がします。

引用返信 編集キー/
■97852 / inTopicNo.5)  Re[3]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ WebSurfer (2304回)-(2021/07/28(Wed) 17:29:43)
No97849 (emi さん) に返信

> 返信ありがとうございます。
> はい、WEBフォームです。
> 「PostBack の際にも動的に追加」はしていて、想定通りにユーザーコントロールの追加と値の保持は出来ています。

追加するタイミングの問題とかはありませんか?

Page_Load ではなく Page_Init で追加してみたらどうなりますか?
引用返信 編集キー/
■97853 / inTopicNo.6)  Re[4]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ emi (5回)-(2021/07/28(Wed) 17:46:38)
No97850 (PATIO さん) に返信
> 2021/07/28(Wed) 17:20:40 編集(投稿者)
>
> Webフォームはやった事が無いので推測になりますが、
> PostBackの際は、AddHandlerはしなくても良いのでしょうか?
> パッと見てコード上の違いはその部分だけのように見えます。
> Webフォームの場合、イベントとハンドラのテーブルが毎回破棄されて作り直されるのであれば、毎回必要になるような気がします。
>

PostBack時の処理に抜けていたので以下を追加しました。
「AddHandler uc.UserControlButtonClicked, AddressOf UserControl_UserControlButtonClicked」

また、AddHandler する場所を、〜.Add(uc)の前に移動しましたが、それでもダメでした。
引用返信 編集キー/
■97861 / inTopicNo.7)  Re[4]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ emi (6回)-(2021/07/29(Thu) 15:13:41)
イベントの取得は修正方法が分かりませんでしたが、別の方法でやりたいことがクリア出来ました。

条件削除ボタンに UseSubmitBehavior="false" を追加し、
メインページの Page_Load で、Request("__EVENTTARGET") から PostBack させたコントロールのIDを取得し、
どのユーザーコントロールの何の動作が行われたかを判断するようにしました。

ご回答くださった皆様、ご協力ありがとうございました。
解決済み
引用返信 編集キー/
■97862 / inTopicNo.8)  Re[5]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ 古谷 (2回)-(2021/07/30(Fri) 11:45:51)
No97861 (emi さん) に返信

怪しいドキュメントを見つけました
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.templatecontrol.loadcontrol?view=netframework-4.8

> コンテナコントロールにコントロールをロードすると、コンテナは追加されたコントロールのすべ
> てのイベントを、現在のイベントに追いつくまで発生させます。しかし、追加されたコントロール
> は、ポストバックのデータ処理に追いつきません。追加されたコントロールが検証を含むポストバ
> ックデータ処理に参加するためには、コントロールをLoadイベントではなくInitイベントで追加す
> る必要があります。

イベントはいつ発火するのだろ
LoadControlのときなのか、Controls.Addのときなのか

Page.LoadControl("../Uc/UserControl.ascx")
Me.PlaceHolder1.Controls.Add(uc)
AddHandler uc.UserControlButtonClicked, AddressOf UserControl_UserControlButtonClicked

これらを行うタイミングとこれらの順番が関わってるっぽい

解決済みとのことなので次回の参考までに

解決済み
引用返信 編集キー/
■97863 / inTopicNo.9)  Re[3]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ WebSurfer (2307回)-(2021/07/30(Fri) 13:54:20)
No97849 (emi さん) に返信

> 「PostBack の際にも動的に追加」はしていて、想定通りにユーザーコントロールの追加と値の保持は出来ています。

質問者さんのコードを見てみましたが、やはりそこのところに問題があるようです。

自分の環境で検証してみましたが、質問者さんが行ったようにポストバックの際 Session からユーザーコントロール
を取得して配置した場合はユーザーコントロールのボタンクリックイベントは発生しません。

初期画面や[条件追加]ボタンクリックで生成したのと同様に Page.LoadControl で生成して配置する必要がありま
す。

Session からユーザーコントロールを取得した場合は ViewState がロードできないということによるのではないかと
思います(想像です)。

なお、No97852 で述べたユーザーコントロールの生成のタイミングが Page_Load か Page_Init は今回のケースでは
影響ないようです。ただ、場合によってはその問題が影響することもありますので、動的なコントロールの追加は、
Microsoft の推奨のとおり Page_Init で行うのが良いと思います。

引用返信 編集キー/
■97871 / inTopicNo.10)  Re[4]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ emi (9回)-(2021/07/30(Fri) 19:25:35)
No97863 (WebSurfer さん) に返信
> ■No97849 (emi さん) に返信
>
>>「PostBack の際にも動的に追加」はしていて、想定通りにユーザーコントロールの追加と値の保持は出来ています。
>
> 質問者さんのコードを見てみましたが、やはりそこのところに問題があるようです。
>
> 自分の環境で検証してみましたが、質問者さんが行ったようにポストバックの際 Session からユーザーコントロール
> を取得して配置した場合はユーザーコントロールのボタンクリックイベントは発生しません。
>
> 初期画面や[条件追加]ボタンクリックで生成したのと同様に Page.LoadControl で生成して配置する必要がありま
> す。
>
> Session からユーザーコントロールを取得した場合は ViewState がロードできないということによるのではないかと
> 思います(想像です)。
>
> なお、No97852 で述べたユーザーコントロールの生成のタイミングが Page_Load か Page_Init は今回のケースでは
> 影響ないようです。ただ、場合によってはその問題が影響することもありますので、動的なコントロールの追加は、
> Microsoft の推奨のとおり Page_Init で行うのが良いと思います。
>

ご回答ありがとうございます。
PostBack時もPage.LoadControlで生成して配置した場合、ViewState による値の保持は期待できないと思うのですが、
それは別途、入力値を保存しておいて、プログラムで1つ1つセットしてあげることになるのでしょうか?


引用返信 編集キー/
■97872 / inTopicNo.11)  Re[5]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ WebSurfer (2309回)-(2021/07/30(Fri) 19:49:43)
No97871 (emi さん) に返信

> PostBack時もPage.LoadControlで生成して配置した場合、ViewState による値の保持は期待できないと思うのですが、
> それは別途、入力値を保存しておいて、プログラムで1つ1つセットしてあげることになるのでしょうか?

聞く前に自分の環境で試してみてはいかが?

あなたの言う「ViewState による値の保持」というのが具体的に何なのか分かりませんが、コントロールには
LoadViewState メソッドというものがあって、動的に追加したコントロールを含めて自動的に ViewState が
ロードされる仕組みがあります。
引用返信 編集キー/
■97873 / inTopicNo.12)  Re[6]: 動的に追加したユーザーコントロールのイベントが取得できない
□投稿者/ emi (10回)-(2021/07/30(Fri) 20:19:08)
No97872 (WebSurfer さん) に返信
> ■No97871 (emi さん) に返信
>
>>PostBack時もPage.LoadControlで生成して配置した場合、ViewState による値の保持は期待できないと思うのですが、
>>それは別途、入力値を保存しておいて、プログラムで1つ1つセットしてあげることになるのでしょうか?
>
> 聞く前に自分の環境で試してみてはいかが?
>
> あなたの言う「ViewState による値の保持」というのが具体的に何なのか分かりませんが、コントロールには
> LoadViewState メソッドというものがあって、動的に追加したコントロールを含めて自動的に ViewState が
> ロードされる仕組みがあります。

申し訳ありません、週明けに試してみます。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -