10

少し異なるページがいくつかありますが、すべてのページに同じタスクを実行する同じ「アクションボタン」があります。コードを複製する代わりに、アクションを実行するボタンを含むユーザーコントロールを作成しましたが、実行できないアクションが1つあります。

各ページにはテキストボックスがあります(ページの異なる場所にあるため、ユーザーコントロール内にはありません)。(ユーザーコントロール内にある)[コメントを保存]ボタンをクリックすると、テキストボックス内のテキストにアクセスできないようです。

私はこのようなものを使ってみました:

TextBox txtComments = (TextBox)this.Parent.FindControl("txtComments");
SaveChanges(txtComments.Text);

...しかし、txtCommentsはnullとして返されます。

だから、これが可能かどうか、あるいは私がやろうとしていることを行うためのより良い方法があるかどうか疑問に思っていますか?

編集:テキストボックスは元のページのプレースホルダーにあります...

編集2:縮小されたソリューションの投稿-まだこれを理解することはできません。

編集3:スペースを節約するためのソリューションを削除しました-問題を解決しました。

4

4 に答える 4

8

私の解決策は驚くほど単純なものになりました。

TextBox txt = this.Parent.Parent.FindControl("ContentPlaceHolder2").FindControl("TextBox1") as TextBox;
if (txt != null) Label1.Text = txt.Text;

以前に間違っていたのは、間違ったContentPlaceHolderIDを使用していたことでした。マスターページのIDではなく、ページのプレースホルダーのIDを使用していました。

于 2013-03-13T14:54:11.147 に答える
1

サーバー側コントロールの共通ベースであるPageによって公開されたプロパティを使用します。WebControl

次に、を使用する代わりに、インスタンスを特定のページタイプにキャストして、コントロールに直接アクセスすることもできます(スコープで許可されている場合)FindControl

于 2013-03-07T15:48:02.170 に答える
1

状況を要約すると、子コントロールからページ上のコントロールのFindControlを実行する必要がありますが、

  1. プロジェクトにMasterPageがありますが、この場合this.Pageは機能しないようです。this.Parent代わり に使用します
  2. 「ターゲット」コントロールはPlaceHolder内にあり、PlaceHolder自体はContentPlaceHolder内にあるため、単純ではありません。this.Parent.FindControl()
  3. 「ターゲット」コントロール(この場合はテキストボックス)を見つけようとしている子ASCXコントロールは、実際には別のContentPlaceHolderにあるため、this.Parent.Parentなどは機能しません。

this.Parentコントロールが互いに異なるContentPlaceHolderにあり、別の子コントロールにあることについての私の最初の回答の後で言及したので、クエリが少し複雑になります。

これらの基準と、ターゲットTextBoxを(その内部のどこかに)含むcontentPlaceHolderコントロールを少なくとも知っているという事実に基づいて、新しいASP.netWebフォームアプリケーションで機能するコードを次に示します。

渡されたContentPlaceHolderのコントロールコレクションを再帰的にチェックし、コントロールを見つけます。

ControlIDとContentPlaceHolderIDを渡すだけで、再帰的に検出されます。

このコードは、ChildControl.ascx.csファイル内にある同じプロジェクトで以下の元のコードを置き換えたものです。

システムを使用する; System.Web.UIを使用します。System.Web.UI.WebControlsを使用します。System.Linqを使用します。System.Collections.Genericを使用します。

namespace FindControlTest
{
    public partial class ChildControl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var textBoxTest = FindControlInContentPlaceHolder("TextBoxTest", "FeaturedContent") as TextBox;

            Response.Write(textBoxTest.Text);
            Response.End();
        }

        private Control FindControlInContentPlaceHolder(string controlID, string contentPlaceHolderID)
        {
            if (null == this.Page ||
                null == this.Page.Master)
            {
                return null;
            }

            var contentPlaceHolder = this.Page.Master.FindControl(contentPlaceHolderID);
            var control = getChildControl(controlID, contentPlaceHolder);
            return control;
        }

        private Control getChildControl(string controlID, Control currentControl)
        {
            if (currentControl.HasControls())
            {
                foreach(Control childControl in currentControl.Controls)
                {
                    var foundControl = childControl.FindControl(controlID);
                    if (null != foundControl)
                    {
                        return foundControl;
                    }
                    else
                    {
                        return getChildControl(controlID, childControl);
                    }
                }
            }

            return null;
        }
    }
}

ノート:

いくつかのイベントでこれを試しましたが、Init()でもTextBox値を取得できました。nullが表示されている場合は、間違ったIDが渡されたか、まだ発生していない状況が原因である可能性があります。追加情報を使用して質問を編集し(多くの情報が含まれているため)、どの変数がnullであるかを示すと、解決できます。

パネル内のPlaceHolderなど、MasterPageに複雑さを追加し、そこにContentPlaceHolderを配置しても、コードは引き続き機能することに注意してください。.net 4.5、4.0、3.5、および3.0用にコンパイルした場合でも、FindControlはMasterPagesとは異なる動作をする可能性があると考えていますが、それでも毎回動作します。それでもnullが発生する場合は、追加のMarkUpを投稿する必要があります。

テストプロジェクトの残りの部分

ページ(デフォルトのMasterPageに基づく)

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FindControlTest._Default" %>
<%@ Register TagName="ChildControl" TagPrefix="uc1" Src="~/ChildControl.ascx" %>

<asp:Content runat="server" ContentPlaceHolderID="FeaturedContent">

    <asp:PlaceHolder ID="PlaceHolderTest" runat="server">
        <asp:TextBox ID="TextBoxTest" Text="Hello!" runat="server"/>
    </asp:PlaceHolder>

</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">

    <uc1:ChildControl id="ChildControlTest" runat="server" />

</asp:Content>

これだけを含むChildControl.ascxというコントロールを追加しました。

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChildControl.ascx.cs" Inherits="FindControlTest.ChildControl" %>
Hello child!

結果は「こんにちは!」です。ページ上。

于 2013-03-07T17:04:03.390 に答える
0

コードビハインドのテキストボックスプロパティにインテリジェンスプロパティとしてアクセスする場合は、ユーザーコントロールの文字列プロパティにするだけです。

1. In the user control, create a public string property that returns textbox string value..

public string MyText
{
get
{
return txt1.Text;
}
}

2. Register the user control on the page

<%@ Register TagPrefix="uc" TagName="MyControl" Src="~/mycontrol.ascx" />

and declare it..

<uc:MyControl ID="control1" runat="server" />

3. From the codebehind now you can read the property..

Response.Write(control1.MyText);

Hope it helps

Thanks...
于 2018-06-08T06:41:43.667 に答える