ASP.NET文本框TextChanged事件没有在自定义EditorPart中触发

问题描述:

这是一个经典的问题,我想,但似乎大多数人都有兴趣让文本框导致回发。我不是。我只是希望事件在发生回发时触发。ASP.NET文本框TextChanged事件没有在自定义EditorPart中触发

我创建了一个带有自定义编辑部分的webpart。编辑器部分使用文本框和按钮进行渲染。点击按钮会打开一个对话框。当对话框关闭时,它通过javascript设置文本框的值,然后使用编辑器部分的ClientID执行__doPostBack

回发发生,但TextChanged事件永远不会触发,我不确定这是否是调用方式__doPostBack的问题,或者是因为我设置事件处理程序的方式,或者某种情况其他。以下是我认为是编辑器部分代码的相关部分:

protected override void CreateChildControls() 
{ 
    _txtListUrl = new TextBox();    

    _txtListUrl.ID = "targetSPList"; 
    _txtListUrl.Style.Add(HtmlTextWriterStyle.Width, "60%"); 
    _txtListUrl.ToolTip = "Select List"; 
    _txtListUrl.CssClass = "ms-input"; 
    _txtListUrl.Attributes.Add("readOnly", "true"); 
    _txtListUrl.Attributes.Add("onChange", "__doPostBack('" + this.ClientID + "', '');"); 
    _txtListUrl.Text = this.ListString;         

    _btnListPicker = new HtmlInputButton(); 
    _btnListPicker.Style.Add(HtmlTextWriterStyle.Width, "60%"); 
    _btnListPicker.Attributes.Add("Title", "Select List"); 
    _btnListPicker.ID = "browseListsSmtButton"; 
    _btnListPicker.Attributes.Add("onClick", "mso_launchListSmtPicker()"); 
    _btnListPicker.Value = "Select List"; 

    this.AddConfigurationOption("News List", "Choose the list that serves as the data source.", 
     new Control[] { _txtListUrl, _btnListPicker }); 

    if (this.ShowViewSelection) 
    { 
     _txtListUrl.TextChanged += new EventHandler(_txtListUrl_TextChanged); 
     _ddlViews = new DropDownList(); 
     _ddlViews.ID = "_ddlViews"; 
     this.AddConfigurationOption("View", _ddlViews); 
    } 
} 

protected override void OnPreRender(EventArgs e) 
{ 
    ScriptLink.Register(this.Page, "PickerTreeDialog.js", true); 

    string lastSelectedListId = string.Empty; 
    if (!this.WebId.Equals(Guid.Empty) && !this.ListId.Equals(Guid.Empty)) 
    { 
     lastSelectedListId = SPHttpUtility.EcmaScriptStringLiteralEncode(
      string.Format("SPList:{0}?SPWeb:{1}:", this.ListId.ToString(), this.WebId.ToString())); 
    } 

    string script = "\r\n    var lastSelectedListSmtPickerId = '" + lastSelectedListId + "';" 
        + "\r\n    function mso_launchListSmtPicker(){" 
        + "\r\n     if (!document.getElementById) return;" 
        + "\r\n" 
        + "\r\n     var listTextBox = document.getElementById('" + SPHttpUtility.EcmaScriptStringLiteralEncode(_txtListUrl.ClientID) + "');" 
        + "\r\n     if (listTextBox == null) return;" 
        + "\r\n" 
        + "\r\n     var serverUrl = '" + SPHttpUtility.EcmaScriptStringLiteralEncode(SPContext.Current.Web.ServerRelativeUrl) + "';" 
        + "\r\n" 
        + "\r\n     var callback = function(results) {" 
        + "\r\n      if (results == null || results[1] == null || results[2] == null) return;" 
        + "\r\n" 
        + "\r\n      lastSelectedListSmtPickerId = results[0];" 
        + "\r\n      var listUrl = '';" 
        + "\r\n      if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';" 
        + "\r\n      if (results[1].charAt(0) == '/') results[1] = results[1].substring(1);" 
        + "\r\n      listUrl = listUrl + results[1];" 
        + "\r\n      if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';" 
        + "\r\n      if (results[2].charAt(0) == '/') results[2] = results[2].substring(1);" 
        + "\r\n      listUrl = listUrl + results[2];" 
        + "\r\n      listTextBox.value = listUrl;" 
        + "\r\n      __doPostBack('" + this.ClientID + "','');" 
        + "\r\n     }" 
        + "\r\n     LaunchPickerTreeDialog('CbqPickerSelectListTitle','CbqPickerSelectListText','websLists','', serverUrl, lastSelectedListSmtPickerId,'','','/_layouts/images/smt_icon.gif','', callback);" 
        + "\r\n    }"; 

    this.Page.ClientScript.RegisterClientScriptBlock(typeof(ListPickerEditorPart), "mso_launchListSmtPicker", script, true); 

    if ((!string.IsNullOrEmpty(_txtListUrl.Text) && _ddlViews.Items.Count == 0) || _listSelectionChanged) 
    { 
     _ddlViews.Items.Clear(); 
     if (!string.IsNullOrEmpty(_txtListUrl.Text)) 
     { 
      using (SPWeb web = SPContext.Current.Site.OpenWeb(this.WebId)) 
      { 
       foreach (SPView view in web.Lists[this.ListId].Views) 
       { 
        _ddlViews.Items.Add(new ListItem(view.Title, view.ID.ToString())); 
       } 
      } 
      _ddlViews.Enabled = _ddlViews.Items.Count > 0; 
     } 
     else 
     { 
      _ddlViews.Enabled = false; 
     } 
    } 

    base.OnPreRender(e); 
} 

void _txtListUrl_TextChanged(object sender, EventArgs e) 
{ 
    this.SetPropertiesFromChosenListString(_txtListUrl.Text); 
    _listSelectionChanged = true; 
} 

任何想法?

更新:我忘了提及这些方法,这是所谓上面:

protected virtual void AddConfigurationOption(string title, Control inputControl) 
{ 
    this.AddConfigurationOption(title, null, inputControl); 
} 

protected virtual void AddConfigurationOption(string title, string description, Control inputControl) 
{ 
    this.AddConfigurationOption(title, description, new List<Control>(new Control[] { inputControl })); 
} 

protected virtual void AddConfigurationOption(string title, string description, IEnumerable<Control> inputControls) 
{ 
    HtmlGenericControl divSectionHead = new HtmlGenericControl("div"); 
    divSectionHead.Attributes.Add("class", "UserSectionHead"); 
    this.Controls.Add(divSectionHead); 

    HtmlGenericControl labTitle = new HtmlGenericControl("label"); 
    labTitle.InnerHtml = HttpUtility.HtmlEncode(title); 
    divSectionHead.Controls.Add(labTitle); 

    HtmlGenericControl divUserSectionBody = new HtmlGenericControl("div"); 
    divUserSectionBody.Attributes.Add("class", "UserSectionBody"); 
    this.Controls.Add(divUserSectionBody); 

    HtmlGenericControl divUserControlGroup = new HtmlGenericControl("div"); 
    divUserControlGroup.Attributes.Add("class", "UserControlGroup"); 
    divUserSectionBody.Controls.Add(divUserControlGroup); 

    if (!string.IsNullOrEmpty(description)) 
    { 
     HtmlGenericControl spnDescription = new HtmlGenericControl("div"); 
     spnDescription.InnerHtml = HttpUtility.HtmlEncode(description); 
     divUserControlGroup.Controls.Add(spnDescription); 
    } 

    foreach (Control inputControl in inputControls) 
    { 
     divUserControlGroup.Controls.Add(inputControl); 
    } 
    this.Controls.Add(divUserControlGroup); 

    HtmlGenericControl divUserDottedLine = new HtmlGenericControl("div"); 
    divUserDottedLine.Attributes.Add("class", "UserDottedLine"); 
    divUserDottedLine.Style.Add(HtmlTextWriterStyle.Width, "100%"); 
    this.Controls.Add(divUserDottedLine); 
} 

它可以帮助,如果类声明事件处理程序(在你的情况的EditorPart,我猜)实现系统.Web.UI.INamingContainer。你是否将_txtListUrl添加到Controls集合中?

编辑:

  • 确保_txtListUrl的AutoPostBack属性设置为true(_txtListUrl.AutoPostBack = TRUE)。

  • _txtListUrl.Attributes.Add("onChange"可能会干扰事件处理程序。

  • 仅当文本框失去焦点时才会调用TextChanged。

+0

很好的问题。起初我认为这是问题 - 我根本没有将控件添加到Controls集合,但可悲的是(我猜),我是。请参阅上面添加的“AddConfigurationOption”方法。 – 2010-06-04 16:54:23

+0

原来我没有设置editorpart的ID。一旦我确定了,事件就开始奏效。我会将你的答案标记为答案,因为你帮助我思考了所有这些机制,即使你没有专门提到这一点。 – 2010-06-07 16:21:44