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

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

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

動的コントロールのカーソルセット

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

■86861 / inTopicNo.1)  動的コントロールのカーソルセット
  
□投稿者/ passop (1回)-(2018/03/29(Thu) 13:09:08)

分類:[ASP.NET (VB)] 

2018/03/29(Thu) 16:48:05 編集(投稿者)
動的にテキストボックスを作成しています。

テキストボックスをAutoPostBack = Trueに設定した場合は
TextChangeイベントでカーソルがどこかに行ってなくなるため、
focusをセットしています。

画面のちらつきをなくすために
UpdatePanelを使用したところ、focusをセットしても
カーソルがどこかに行ってしまいます。

UpdatePanelパネルはUpdateModeをAlwaysに設定しております。

動的にテキストボックスを作成する場合、
UpdatePanelを使用して、カーソルが消えないようにするには
どのようにすればよいかどなたかご存知ないでしょうか?

(以下コード)
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'ポストバックの場合
        'ページ内のTableコントロールからデータセットを作成
        If IsPostBack Then
            TextBoxButtonMaking(Table1, 1)
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Me.TextBoxButtonMaking(Table1, 1)

    End Sub

    '//////// 動的TextBox+Buttonコントロール作成ルーチン /////
    Private Sub TextBoxButtonMaking(ByVal tTable As Table, ByVal No As Integer)
        '行数
        Dim rowCnt As Integer = 3
        '列数
        Dim colCnt As Integer = 3

        If tTable.Rows.Count > 0 Then
            Exit Sub
        End If

        For j = 1 To rowCnt
            Dim tRow As New TableRow()
            For i As Integer = 1 To colCnt
                AddCellCreate(tRow, j, i, No)
            Next i
            'テーブルに新しい行を追加
            tTable.Rows.Add(tRow)

        Next j

    End Sub

    Private Sub AddCellCreate(ByVal tRow As TableRow, ByVal rowCtr As Integer, ByVal cellCtr As Integer, ByVal TableNo As Integer)

        Dim prodID As String = ""
        'IDを作成

        prodID = TableNo.ToString & "_" & rowCtr & "_" & cellCtr

        Dim tCell As New TableCell()
        tCell.HorizontalAlign = HorizontalAlign.Center
        tCell.Wrap = False
        tCell.ViewStateMode = UI.ViewStateMode.Enabled
        'TextBoxコを作成
        Dim ctrl As New TextBox
        ctrl.ID = "txt" & prodID
        ctrl.Text = ctrl.ID
        ctrl.AutoPostBack = True
        ctrl.EnableViewState = True
        AddHandler ctrl.TextChanged, AddressOf txtBox_TextChanged

        'セルに追加
        tCell.Controls.Add(ctrl)
        '行に新しいセルを追加
        tRow.Cells.Add(tCell)

    End Sub

    Private Sub txtBox_TextChanged(ByVal sender As System.Object, ByVal e As EventArgs)
        Dim tb As TextBox

        tb = Master.FindControl("MainContent").FindControl(sender.ID)
        SetFocusText(tb)

    End Sub

   Sub SetFocusText(ByVal ctrl As Control)
        Dim script As String = _
          "<script language='JavaScript'>" _
          + "document.getElementById('" _
          + ctrl.ClientID _
          + "').focus(); <" + "/script>"
        Me.ClientScript.RegisterStartupScript(Me.GetType(), "setfocus", script)

    End Sub

引用返信 編集キー/
■86862 / inTopicNo.2)  Re[1]: 動的コントロールのカーソルセット
□投稿者/ WebSurfer (1446回)-(2018/03/29(Thu) 13:28:03)
No86861 (passop さん) に返信

「図表モード」を選択してコードを貼りなおしてもらえませんか?

インデントされてないコードは非常に読み難いですので。
引用返信 編集キー/
■86863 / inTopicNo.3)  Re[2]: 動的コントロールのカーソルセット
□投稿者/ passop (2回)-(2018/03/29(Thu) 16:43:33)
2018/03/29(Thu) 16:44:42 編集(投稿者)

No86862 (WebSurfer さん) に返信
> ■No86861 (passop さん) に返信
>
> 「図表モード」を選択してコードを貼りなおしてもらえませんか?
>
> インデントされてないコードは非常に読み難いですので。

申し訳ありませんでした。

「編集」で「図表モード」にて更新しました。
最初の分で見てください。

引用返信 編集キー/
■86864 / inTopicNo.4)  Re[1]: 動的コントロールのカーソルセット
□投稿者/ WebSurfer (1447回)-(2018/03/29(Thu) 18:57:20)
No86861 (passop さん) に返信

UpdatePanel + ScriptManager を利用した非同期ポストバックを行場合、サーバーから応答
として返ってくるのは UpdatePanel の中身と ViewState のみになります。

なので、フォーカスを当てるためのスクリプトは動きません。それが原因であろうと思われ
ます。

ScriptManager と UpdatePanel コントロールを使用しての非同期ポストバックは、内部で
XMLHttpRequest オブジェクトを呼び出す PageRequestManager クライアントオブジェクトが
関係しています。

PageRequestManager が提供している以下のイベントを利用して、開発者が部分ページ更新
のリクエストとレスポンスの処理をカスタマイズできます。

&#8226; initializeRequest
&#8226; beginRequest
&#8226; pageLoading
&#8226; pageLoaded
&#8226; endRequest

詳しくは以下の記事を見てください。

ASP.NET PageRequestManager クラスの概要
https://docs.microsoft.com/ja-jp/previous-versions/visualstudio/visual-studio-2008/bb386571(v=vs.90)

PageRequestManager のイベントの処理
https://docs.microsoft.com/ja-jp/previous-versions/visualstudio/visual-studio-2008/bb398976(v=vs.90)

今回の場合、pageLoaded イベントにリスナをアタッチして、そのリスナでフォーカスを当て
るようにしたらいかがですか?

引用返信 編集キー/
■86893 / inTopicNo.5)  Re[3]: 動的コントロールのカーソルセット
□投稿者/ WebSurfer (1449回)-(2018/04/02(Mon) 12:18:23)
No86863 (passop さん) に返信

レスに対するフィードバック(役に立った/立たない、分かった/分からない、回答になっている/なっていない等々)を
いただけますか?

引用返信 編集キー/
■86906 / inTopicNo.6)  Re[2]: 動的コントロールのカーソルセット
□投稿者/ passop (3回)-(2018/04/02(Mon) 17:10:08)
■86893 (WebSurfer さん) に返信

レス返せなくで申し訳ありません。

内容が深すぎて・・・
後2、3日お時間をください。
内容を吟味させて頂きたいと思います。
引用返信 編集キー/
■86907 / inTopicNo.7)  Re[3]: 動的コントロールのカーソルセット
□投稿者/ WebSurfer (1451回)-(2018/04/02(Mon) 18:53:25)
No86906 (passop さん) に返信

> 後2、3日お時間をください。
> 内容を吟味させて頂きたいと思います。

了解しました。
不明点・疑問点があれば問い合わせてください。
引用返信 編集キー/
■86938 / inTopicNo.8)  Re[4]: 動的コントロールのカーソルセット
□投稿者/ passop (4回)-(2018/04/04(Wed) 14:53:26)
2018/04/04(Wed) 14:58:41 編集(投稿者)
No86907 (WebSurfer さん) に返信

PageRequestManager のイベントの処理に関して、理解できていないようです。

以下のようにコードを定義しました。

    <script type = "text/jscript">
        // ページ・ロード時に呼び出されるpageLoad関数
        function pageLoad() {

            // PageRequestManagerクラスをインスタンス化
            var mng = Sys.WebForms.PageRequestManager.getInstance();

            // pageLoadedイベント・ハンドラを定義
            mng.add_pageLoaded(

              // 非同期ポストバックの開始前に、
              // イベント発生元の要素(ID値)にカーソルをセット
              function (sender, args) {
                  document.getElementById(args.get_postBackElement().id).focus();
              }
            );
        }
    </script>

実行した場合、

「0x800a01b6 - JavaScript 実行時エラー: オブジェクトは 'get_postBackElement' 
プロパティまたはメソッドをサポートしていません。」

とエラーになってしまいます。

initializeRequestイベント・ハンドラの定義であれば、
args.get_postBackElement().idはエラーになりません。

pageLoadedのイベント・ハンドラを使用して
動的コントロールにfocusをセットするのにどのようにすれば良いでしょうか?

引用返信 編集キー/
■86941 / inTopicNo.9)  Re[5]: 動的コントロールのカーソルセット
□投稿者/ WebSurfer (1452回)-(2018/04/04(Wed) 17:32:52)
No86938 (passop さん) に返信

> initializeRequestイベント・ハンドラの定義であれば、
> args.get_postBackElement().idはエラーになりません。

その通りですので(pageLoaded のイベント・ハンドラでは取得できないので)、

> pageLoadedのイベント・ハンドラを使用して
> 動的コントロールにfocusをセットするのにどのようにすれば良いでしょうか?

initializeRequestイベント・ハンドラで取得して id を保持しておき、pageLoaded のイベント・ハンドラで保持した id を使ってフォーカスを当てるようにしてはいかがですか?

以下のような感じです。

<%@ Page Language="C#" AutoEventWireup="true" 
    CodeFile="0027-UpdatePanelTextBoxFocus.aspx.cs" 
    Inherits="_0027_UpdatePanelTextBoxFocus" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
    <script type="text/javascript">
        //<![CDATA[
        var manager;
        var postBackElementId;

        function pageLoad(sender, args) {
            if (args.get_isPartialLoad() === false) {
                manager = Sys.WebForms.PageRequestManager.getInstance();
                manager.add_initializeRequest(OnInitializeRequest);
                manager.add_pageLoaded(OnPageLoaded);
            }
        }

        function OnInitializeRequest(sender, args) {
            postBackElementId = args.get_postBackElement().id;
        }

        function OnPageLoaded(sender, args) {
            if (postBackElementId) {
                var elem = document.getElementById(postBackElementId);
                elem.focus();
            }
        }
        //]]>
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <div style="border: solid 1px Silver; padding: 2px 5px;">
            UpdatePanel<hr />
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    TextBox1: 
                    <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True" />
                    <br />
                    TextBox2: 
                    <asp:TextBox ID="TextBox2" runat="server" AutoPostBack="True" />
                    <br />
                    TextBox3: 
                    <asp:TextBox ID="TextBox3" runat="server" AutoPostBack="True" />
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
    </form>
</body>
</html>

あとは隠しフィールドを使うという手もあります。ここまでやる必要はないとは思いますが、興味があれば以下の記事を見てください。

UpdatePanel 内の TextBox に focus
http://surferonwww.info/BlogEngine/post/2010/11/21/Focus-on-TextBox-in-UpdatePanel.aspx

記事には IE8 ではフォーカスが当たらないと書いてありますが、IE11 なら問題ないです。IE9, 10 は不明。

引用返信 編集キー/
■86958 / inTopicNo.10)  Re[6]: 動的コントロールのカーソルセット
□投稿者/ passop (6回)-(2018/04/05(Thu) 13:19:12)
No86941 (WebSurfer さん) に返信
こちらがやりたい思ってた通りに正しく動作しました。

わざわざソースまで書いて教えて頂き、
ありがとうございました。

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

このトピックをツリーで一括表示


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

このトピックに書きこむ