none
マスターページの子画面でAjaxControlToolkitのTabContainerが使用できない RRS feed

  • 質問

  • こんにちは、VB2008でWEBアプリを開発しています。

    マスターページの子画面で、AjaxControlToolkitのTabContainer&TabPanelを
    使いたいのですが、次のように配置しただけですが、エラーが発生してしまいます。

    コード↓↓↓↓↓
    <asp:Content ID="Content3" ContentPlaceHolderID="Cont_BodyArea" runat="server">
       
        <ajaxToolkit:TabContainer ID="AJ_Tabs" runat="server" ActiveTabIndex="0" Width=95%>
            <ajaxToolkit:TabPanel runat="server" HeaderText="基本情報" ID="Tab_Kihon">
                <ContentTemplate>
                <p>
                    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                    <asp:Button ID="Button1" runat="server" Text="Button" />
                </p>
                </ContentTemplate>
            </ajaxToolkit:TabPanel>
        </ajaxToolkit:TabContainer>
       
    </asp:Content>
    コード↑↑↑↑↑

    エラー↓↓↓↓↓

    '/' アプリケーションでサーバー エラーが発生しました。

    コントロールにコード ブロック (<% ... %>) が含まれているため、コントロールのコレクションを変更できません。
    エラー↑↑↑↑↑

    自分では、子画面に(<% ... %>)は記述していないので、Tabコントロールが生成しているのでしょうか。
    マスターページを使用していない画面では、エラーは出ませんでした。
    また、画面を開くだけでこのようになる場合は、どのようにデバッグするものでしょうか?
    サーバ側のPage_Loadは最後の行まで問題なく動作していました。

    よろしくお願いします。





    2009年10月22日 7:50

回答

  • Calendar の場合も同様な問題が起こっているようです。

    The Controls collection cannot be modified because the control contains code blocks (i.e. <% … %>)
    http://www.techproszone.net/blog/index.php/2009/01/21/systemwebhttpexception-the-controls-collection-cannot-be-modified-because-the-control-contains-code-blocks-ie/

    理由は分かりませんが、Calendar や TabContainer は AjaxControlToolkit.ScriptObjectBuilder クラ
    スの RegisterCssReferences メソッドを起動し、<head> に HTML link 要素 (CSS) を追加しようとします。
    その時に <head> にコードブロック(今回の場合は <%=Hdn_GamenKind.ClientID%> )があると例外
    をスローするということのようです。

    解決策は、上記の web ページに書いてあるように、以下の方法しかないと思います。

    (1) '<%=Hdn_GamenKind.ClientID%>' に替えて、実際の ClientID を使う。

    (2) 問題の JavaScript を <head> から <body> に移動する。

    • 回答としてマーク ボビン 2009年10月26日 0:21
    2009年10月23日 15:57

すべての返信

  • アップされていたコードそのもので検証してみましたが、そのようなエラーは起こりません。

    質問に書いてないコードが他に多々あってそれが問題を起こしているのではないですか?

    そういう場合はコードを問題が再現できる必要最小限まで削って、すべてのコードをアップ
    してもらえると、当方でも検証できるので、お役に立てるかもしれません。
    2009年10月22日 14:59
  • SurferOnWwwさん、お返事ありがとうございます。

    おっしゃる通りです。必要最小限まで削りました。
    マスターページのJavaScriptにてエラーが発生していまして、
    エラーの発生する行は特定できましたが、悔しいのですが力不足で原因がわかりません。

    削ったコードの全てを記載します。

    マスターページ↓↓↓↓↓
    <%@ Master Language="VB" AutoEventWireup="false" CodeBehind="Site1.master.vb" Inherits="GaikinWeb.Site1" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>

        <script type="text/javascript"><!--
            function gamenKindChk() {
                var gamenKind = $get('<%=Hdn_GamenKind.ClientID%>')     // この行でエラー発生
            }
        --></script>

    </head>
    <body>
        <form id="form1" runat="server">
       
            <ajaxToolkit:ToolkitScriptManager ID="manager" runat="server">
            </ajaxToolkit:ToolkitScriptManager>

            <asp:HiddenField ID="Hdn_GamenKind" runat="server" />

            <div id="BodyView">
                <asp:ContentPlaceHolder ID="Cont_BodyArea" runat="server">
               
                </asp:ContentPlaceHolder>
            </div>
       
        </form>
    </body>
    </html>
    マスターページ↑↑↑↑↑

    子画面↓↓↓↓↓
    <%@ Page Title="" Language="vb" AutoEventWireup="false" MasterPageFile="~/Site1.Master" CodeBehind="WebForm2.aspx.vb" Inherits="GaikinWeb.WebForm2" %>

    <asp:Content ID="Content3" ContentPlaceHolderID="Cont_BodyArea" runat="server">

        <ajaxToolkit:TabContainer ID="TabContainer1" runat="server" ActiveTabIndex="1" Height="160px" Width="359px">
       
            <ajaxToolkit:TabPanel runat="server" HeaderText="TabPanel1" ID="TabPanel1">
                <ContentTemplate>あいう</ContentTemplate>
            </ajaxToolkit:TabPanel>
           
            <ajaxToolkit:TabPanel ID="TabPanel2" runat="server" HeaderText="TabPanel2">
                <ContentTemplate>えお</ContentTemplate>
            </ajaxToolkit:TabPanel>
           
        </ajaxToolkit:TabContainer>

    </asp:Content>
    子画面↑↑↑↑↑

    サーバ側には何も記述していません。

    var gamenKind = $get('<%=Hdn_GamenKind.ClientID%>')     // この行でエラー発生

    この行を削るか、子画面のtabコントロールを削れば画面は表示されます。

    よろしくお願いします。

    2009年10月23日 1:13
  • 自己レスです。

    この問題の行を、
    var gamenKind = $get('<%=Hdn_GamenKind.ClientID%>')

    以下のように書き換えると、うまくいきました。
    var gamenKind = document.getElementById("ctl00_Hdn_GamenKind")


    ですが、なぜ他の画面では上の書き方でもOKで、tabを使用した画面ではダメなのでしょう?
    もしおわかりであれば、予想でも構いませんので、教えて下さい。
    この原因がわからないと、tabだけでなく他のコントロールの時も同じようなエラーが
    発生するかもしれません。



    • 回答としてマーク ボビン 2009年10月26日 0:21
    • 回答としてマークされていない ボビン 2009年10月26日 0:21
    2009年10月23日 1:48
  • Calendar の場合も同様な問題が起こっているようです。

    The Controls collection cannot be modified because the control contains code blocks (i.e. <% … %>)
    http://www.techproszone.net/blog/index.php/2009/01/21/systemwebhttpexception-the-controls-collection-cannot-be-modified-because-the-control-contains-code-blocks-ie/

    理由は分かりませんが、Calendar や TabContainer は AjaxControlToolkit.ScriptObjectBuilder クラ
    スの RegisterCssReferences メソッドを起動し、<head> に HTML link 要素 (CSS) を追加しようとします。
    その時に <head> にコードブロック(今回の場合は <%=Hdn_GamenKind.ClientID%> )があると例外
    をスローするということのようです。

    解決策は、上記の web ページに書いてあるように、以下の方法しかないと思います。

    (1) '<%=Hdn_GamenKind.ClientID%>' に替えて、実際の ClientID を使う。

    (2) 問題の JavaScript を <head> から <body> に移動する。

    • 回答としてマーク ボビン 2009年10月26日 0:21
    2009年10月23日 15:57
  • SurferOnWwwさん、お返事遅くなりすみません。

    > 理由は分かりませんが、Calendar や TabContainer は AjaxControlToolkit.ScriptObjectBuilder クラ
    スの RegisterCssReferences メソッドを起動し、<head> に HTML link 要素 (CSS) を追加しようとします。
    その時に <head> にコードブロック(今回の場合は <%=Hdn_GamenKind.ClientID%> )があると例外
    をスローするということのようです。

    なるほど、そういう動きに関連した例外なのですね。情報ありがとうございます。
    解決策の(1)を試してみます。
    ありがとうございました。
    2009年10月26日 0:21
  • > 解決策の(1)を試してみます。

    自分は (2) が正解だと思います。

    MasterPage は他の方が作られたのではないかと思いますが、その方がわざわざ

    $get('<%=Hdn_GamenKind.ClientID%>'

    としたのはそれなりに意味があると思います。
    2009年10月26日 12:48
  • SurferOnWwwさん、お返事いただいていたことに気づきませんでした。
    すみません。

    > MasterPage は他の方が作られたのではないかと思いますが、その方がわざわざ
    $get('<%=Hdn_GamenKind.ClientID%>'
    としたのはそれなりに意味があると思います。

    あ、MasterPageは私が作りました。
    $get('<%=Hdn_GamenKind.ClientID%>' としたのは、
    調べながら試行錯誤している内にこの形に落ち着いたからでした(汗)。
    この実装方法は「わざわざ」というものなのでしょうか?
    2009年11月9日 12:01
  • > $get('<%=Hdn_GamenKind.ClientID%>' としたのは、
    > 調べながら試行錯誤している内にこの形に落ち着いたからでした(汗)。
    > この実装方法は「わざわざ」というものなのでしょうか?

    ClientID は「ASP.NET によって生成されたサーバー コントロール ID」だそうで、プログラマがコード
    の中に直接書くものではないようです。

    コントロールを配置する場所によって変わりますし、コードをいじらなくても将来の ASP.NET の仕様の
    変更で変わるかもしれません。

    一方、<%=Hdn_GamenKind.ClientID%>' とすれば間違いなく Hdn_GamenKind の ClientID
    を取得できます。

    AJAX Control Toolkit のサンプルや本などでそのような使い方になっているのは、そういう理由があ
    るからだと思います。

    2009年11月9日 13:40
  • SurferOnWwwさん、お返事ありがとうございます。

    そういった違いがあるのですね。このあたりをもう少し調べてみます。
    教えていただいてありがとうございました。
    2009年11月10日 0:13