这是一个经典的问题,我想,但似乎大多数人都对文本框导致回发感兴趣。我不是。我只是希望在发生回发时触发事件。
我创建了一个带有自定义编辑器部分的webpart。编辑部分使用文本框和按钮进行渲染。单击该按钮将打开一个对话框。关闭对话框后,它会通过javascript设置文本框的值,然后使用编辑部分的__doPostBack
执行ClientID
。
回发发生,但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);
}
答案 0 :(得分:1)
如果声明事件处理程序的类(在您的情况下是编辑部分,我猜)实现System.Web.UI.INamingContainer,它可以提供帮助。你是否将_txtListUrl添加到Controls集合中?
编辑:
确保_txtListUrl的AutoPostBack属性设置为true(_txtListUrl.AutoPostBack = true)。
_txtListUrl.Attributes.Add("onChange"
可能会干扰事件处理程序。
只有在文本框失去焦点时才会调用TextChanged。