1

我需要在由JavaScript自定義控件的最新文本集。當我嘗試從服務器控件中獲取所選文本時,它總是返回默認文本&而不是修改後的文本。如何在servercontrol中保留javascript設置的最新值?下面是供您參考的完整代碼..獲取選定的文本asp.net自定義服務器控件

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; 
} 

回答

2

除非您將更改發佈給他,否則服務器將不會獲取您的客戶端更改。你HtmlAnchors在HTML渲染爲<a>控制,而這些類型的控件將不會發布任何服務器。

你會需要一個<input>控制輸入變爲服務器(這就是爲什麼他們是所謂的輸入控件畢竟)。我建議<input type=hidden>保持anchor.innerText的值並保持其狀態。

你的JavaScript函數需要進行修改,以便它更新anchor.innerText和更新隱藏的輸入值,以及。通過這種方式,當頁面發回服務器時,您可以從隱藏字段中檢索更新後的客戶端修改的值。

首先,你需要將其定義爲你要插入私有字段您selectedTextAnchorhiddenField。這是因爲您需要在CreateChildControls方法以及Text屬性的getter和setter中訪問它們。部分設計器類在很大程度上定義了您希望在代碼隱藏中可用的控件。

ServerControl.cs

private HtmlAnchor selectedTextAnchor; 
private HtmlInputHidden hiddenField; 

在CreateChildControls方法需要插入隱藏字段。

你會發現我刪除了使用ClientIDMode.Static的。使用該模式將使您的客戶端控件具有相同的固定ID和Javascript,當您在頁面中存在多個ServerControl副本時可能會感到困惑,從而失去了自定義控件的可重用目的。

相反,您需要爲您的Javascript函數提供需要修改的控件的ClientID。 這裏的關鍵是您需要將控件附加到控件的層次結構中,然後才能獲得其ClientID。

只要你做this.Controls.Add(dummyControl),你讓dummyControl成爲頁的一部分,它的dummyControl.ClientID會突然改變,以反映你將其附着到頁面的層次結構。

我更改了控件的控件集合的順序,這樣我們就可以在構建onclick屬性時傳遞參數,以便您的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屬性的方式。

當你GET屬性你需要檢查它是否是一個回發,如果是,那麼你想檢查瀏覽器的所有信息中是否有你的HiddenInputField。您可以在Request對象中更詳細地獲取來自客戶端的所有信息,更具體地說,就是在Request.Form中。

Request.Form.AllKeys

您的網頁上的所有啓用的輸入控件將Request.Form集合的一部分,您可以通過使用Request.Form[anyInputControl.UniqueID]得到他們的價值觀。請注意,用於此對象的密鑰是UniqueID,而不是ClientID。

從隱藏輸入中獲得客戶端修改的值後,將其值分配給selectedTextAnchor,否則將返回到原始的「Select ...」文本。

當你SET屬性,你只需要將它分配到selectedTextAnchor

get和set你需要調用EnsureChildControls(),這實際上將打電話給你CreateChildControls(),以確保您的selectedTextAnchorhiddenField控件實例化你試圖讓它們的一些屬性之前。幾乎與Composite Controls完成的方式完全相同。

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請求單擊鏈接時注意到服務器,但這需要全新的不同代碼。

祝你好運!

相關問題