1

javascriptでカスタムコントロールに設定された最新のテキストを取得する必要があります。サーバーコントロールから選択したテキストを取得しようとすると、変更されたテキストではなく、常にデフォルトのテキストが返されます。servercontrolでjavascriptによって設定された最新の値を保持するにはどうすればよいですか?以下は、参照用の完全なコードです。

ServerControl1.cs

[assembly: WebResource("ServerControl1.Scripts.JScript1.js", "text/javascript")]
namespace ServerControl1
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:ServerControl1 runat=server></{0}:ServerControl1>")]
public class ServerControl1 : WebControl
{
    public List<string> ListItems
    {
        get
        {
            return ViewState["items"] as List<string>;
        }
        set
        {
            ViewState["items"] = value;
        }
    }

    public string Text
    {
        get
        {
            return (FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor).InnerText;
        }
        set
        {
            ((FindControl("middleDiv").FindControl("anchorID") as HtmlAnchor)).InnerText = value;
        }
    }

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div");
        selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static;
        selectedTextContainer.ID = "middleDiv";

        HtmlAnchor selectedTextAnchor = new HtmlAnchor();
        selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static;
        selectedTextAnchor.ID = "anchorID";
        selectedTextAnchor.HRef = "";
        selectedTextContainer.Controls.Add(selectedTextAnchor);

        HtmlGenericControl unList = new HtmlGenericControl("ul");

        foreach (string item in ListItems)
        {
            HtmlGenericControl li = new HtmlGenericControl("li");
            HtmlAnchor anchor = new HtmlAnchor();
            anchor.HRef = "";
            anchor.Attributes.Add("onclick", "updateData()");
            anchor.InnerText = item;
            li.Controls.Add(anchor);
            unList.Controls.Add(li);
        }

        selectedTextContainer.Controls.Add(unList);
        Controls.Add(selectedTextContainer);

        ChildControlsCreated = true; 
    }

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        string resourceName = "ServerControl1.Scripts.JScript1.js";

        ClientScriptManager cs = this.Page.ClientScript;
        cs.RegisterClientScriptResource(typeof(ServerControl1), resourceName);
    }
 }
}

JScript1.js

function updateData() {
var evt = window.event || arguments.callee.caller.arguments[0];
var target = evt.target || evt.srcElement;
var anchor = document.getElementById("anchorID");
anchor.innerText = target.innerText;
return false;
}

TestPageコードビハインド

protected void Page_Load(object sender, EventArgs e)
{
  if (!Page.IsPostBack)
  {
     List<string> items = GetDataSource();
     ServerControl1.ListItems = items;
     ServerControl1.Text = "Select ..";
  }
}
protected void ClientButton_Click(object sender, EventArgs e)
{
   string selectedText = ServerControl1.Text;
 }
4

1 に答える 1

2

サーバーに変更をPOSTしない限り、サーバーはクライアントの変更を取得しません。HtmlAnchorsは<a>コントロールとしてHTMLでレンダリングされており、これらのタイプのコントロールはサーバーに何もPOSTしません。

変更をサーバーに入力するためのコントロールが必要<input>になります(そのため、変更は結局入力コントロールと呼ばれます)。<input type=hidden>の値を保持し、anchor.innerTextその状態を維持することをお勧めします。

Javascript関数を変更してanchor.innerText、非表示の入力値も更新するようにする必要があります。このようにして、ページがサーバーにポストバックされたときに、更新され、クライアントが変更した値を非表示フィールドから取得できます。

まず、あなたとあなたが挿入しようとしているあなたselectedTextAnchorとあなたがプライベートフィールドとして定義する必要があります。hiddenFieldこれは、CreateChildControlsメソッドと、youtTextプロパティのgetterおよびsetterでそれらにアクセスする必要があるためです。部分的なデザイナクラスが、コードビハインドで使用できるようにするコントロールを定義する方法と同じです。

ServerControl.cs

private HtmlAnchor selectedTextAnchor;
private HtmlInputHidden hiddenField;

CreateChildControlsメソッドで、非表示フィールドを挿入する必要があります。

ClientIDMode.Staticの使用を削除したことに気付くでしょう。このモードを使用すると、クライアントコントロールが同じ固定IDを持つようになり、ページにServerControlの複数のコピーがある場合、Javascriptが混乱し、カスタムコントロールの再利用可能な目的が失われる可能性があります。

代わりに、変更する必要のあるコントロールのClientIDをJavascript関数に提供する必要があります。 ここで重要なのは、ClientIDを取得する前に、コントロールをコントロールの階層にアタッチする必要があるということです。

するとすぐに、this.Controls.Add(dummyControl)dummyControlがページの一部になるようになり、アタッチ先dummyControl.ClientIDのページの階層を反映するように突然変更されます。

コントロールがコントロールのコレクションにアタッチされる順序を変更して、onclick属性を作成するときにクライアントIDを取得してパラメーターを渡すことができるようにしました。これにより、Javascript関数が影響を受けるアンカーとhiddenFieldを認識できるようになります。

ServerControl.cs

protected override void CreateChildControls()
{
    base.CreateChildControls();

    // Instantiate the hidden input field to include
    hiddenField = new HtmlInputHidden();
    hiddenField.ID = "ANCHORSTATE";

    // Insert the hiddenfield into the Control's Collection hierarchy
    // to ensure that hiddenField.ClientID contains all parent's NamingContainers
    Controls.Add(hiddenField);

    HtmlGenericControl selectedTextContainer = new HtmlGenericControl("div");
    // REMOVED: selectedTextContainer.ClientIDMode = System.Web.UI.ClientIDMode.Static;
    selectedTextContainer.ID = "middleDiv";

    selectedTextAnchor = new HtmlAnchor();
    // REMOVED: selectedTextAnchor.ClientIDMode = System.Web.UI.ClientIDMode.Static;
    selectedTextAnchor.ID = "anchorID";
    selectedTextAnchor.HRef = "";
    selectedTextContainer.Controls.Add(selectedTextAnchor);

    // Insert the selectedTextContainer (and its already attached selectedTextAnchor child) 
    // into the Control's Collection hierarchy
    // to ensure that selectedTextAnchor.ClientID contains all parent's NamingContainers
    Controls.Add(selectedTextContainer);

    HtmlGenericControl unList = new HtmlGenericControl("ul");

    foreach (string item in ListItems)
    {
        HtmlGenericControl li = new HtmlGenericControl("li");
        HtmlAnchor anchor = new HtmlAnchor();
        anchor.HRef = "";

        // The updateData function is provided with parameters that will help
        // to know who's triggering and to find the anchor and the hidden field.
        // ClientID's are now all set and resolved at this point.
        anchor.Attributes.Add("onclick", "updateData(this, '" + selectedTextAnchor.ClientID + "', '" + hiddenField.ClientID + "')");
        anchor.InnerText = item;
        li.Controls.Add(anchor);
        unList.Controls.Add(li);
    }

    selectedTextContainer.Controls.Add(unList);
}

updateData関数でのキーワードの使用に注意してthisください。これは、アクションをトリガーしているオブジェクトを取得するのに役立ちます。また、両方のIDが文字列として渡されることに注意してください(一重引用符付き)

Javascript関数は、アンカーと非表示の入力フィールドを更新するように変更する必要があります。

JScript1.js

    function updateData(sender, anchorId, hidFieldId) {
            // Update the anchor
            var anchor = document.getElementById(anchorId);
            anchor.innerText = sender.innerText;
            // Update the hidden Input Field
            var hidField = document.getElementById(hidFieldId);
            hidField.value = sender.innerText;
            return false;
        }

最後に行うことは、Textプロパティの設定と取得の方法を変更することです。

プロパティを取得するときは、それがポストバックであるかどうかを確認する必要があります。そうである場合は、ブラウザからのすべての情報の中にHiddenInputFieldがあるかどうかを確認する必要がありますクライアントからのすべての情報は、Requestオブジェクト、より具体的にはRequest.Formで取得できます。

Request.Form.AllKeys

ページで有効になっているすべての入力コントロールはRequest.Formコレクションの一部になり、を使用してそれらの値を取得できますRequest.Form[anyInputControl.UniqueID]。このオブジェクトに使用されるキーは、ClientIDではなくUniqueIDであることに注意してください。

非表示の入力からクライアントが変更した値を取得したら、その値をに割り当てますselectedTextAnchor。そうしないと、元の「選択...」テキストに戻ります。

プロパティを設定するときは、プロパティをに割り当てる必要がありますselectedTextAnchor

GETとSETの両方で、を呼び出す必要があります。これEnsureChildControls()により、実際にを呼び出して、プロパティの一部を取得しようとする前に、コントロールがインスタンス化CreateChildControls()されていることを確認します。コンポジットコントロールで行われるのとほぼ同じ方法です。selectedTextAnchorhiddenField

ServerControl.cs

public string Text
{
    get
    {
        EnsureChildControls();
        if (this.Page.IsPostBack)
        {
            string HiddenFieldPostedValue = Context.Request.Form[hiddenField.UniqueID];
            // Assign the value recovered from hidden field to the Anchor
            selectedTextAnchor.InnerText = HiddenFieldPostedValue;
            return HiddenFieldPostedValue;
        }
        else
        {
            return selectedTextAnchor.InnerText;
        }
    }
    set
    {
        EnsureChildControls();
        selectedTextAnchor.InnerText = value;
    }
}

このようにして、クライアントで行われた変更を認識するコントロールを持つことができます。サーバーは、クライアントに気付かない限り、クライアントの変更を認識しないことに注意してください。

別のアプローチは、ajaxリクエストを介してリンクをクリックするたびにサーバーに通知することですが、これにはまったく新しい異なるコードが必要になります。

幸運を!

于 2012-05-24T18:32:07.397 に答える