我正在尝试创建自己的转发器控件版本。它不是DataBoundControl;它不会绑定到DataSource,DataSourceID,DataBind方法等等。它有一个嵌套在其中的模板,以及一个名为RepeatCount
的属性,它将重复模板内部的任何内容,如上述财产。
但是,如果在模板中添加文本框和与其关联的自动完成扩展程序,则会自动完成自动完成功能。这是一个显示一系列问题的图像:
请注意生成的文本框ID。我添加的只是一个TextBox
模板内部ID="TextBox1"
,但名称/ ID相同
重复多次。
您可以看到文本框可见。要理解它为什么
可见,查看后面的代码并查看ItemPreRender事件
我已经处理过(在aspx页面上)。如果我没有写那样的代码
我有例外说:
这可能是什么问题?如果将其正确放入转发器控件并以类似的方式工作,那么它将起作用......
那我在这里错过了什么?
以下是我分享的部分源代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyRepeaterComplex.aspx.cs" Inherits="RelationalGridView.Web.MyRepeaterComplex" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc2" %>
<%@ Register Assembly="WebGui.Extensions" Namespace="WebGui.Extensions.MyRepeater"
TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>MyRepeater Sample</title>
<style type="text/css">
/*AutoComplete flyout */
.autocomplete_completionListElement
{
margin : 0px!important;
background-color : inherit;
color : windowtext;
border : buttonshadow;
border-width : 1px;
border-style : solid;
cursor : 'default';
overflow : auto;
height : 200px;
text-align : left;
list-style-type : none;
}
/* AutoComplete highlighted item */
.autocomplete_highlightedListItem
{
background-color: #ffff99;
color: black;
padding: 1px;
}
/* AutoComplete item */
.autocomplete_listItem
{
background-color : window;
color : windowtext;
padding : 1px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<cc1:MyRepeater ID="MyRepeater1" runat="server" RepeatCount="10">
<Template>
<p>Enter Name: <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></p>
<cc2:AutoCompleteExtender
ID="AutoCompleteExtender1"
runat="server"
TargetControlID="TextBox1"
ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList"
MinimumPrefixLength="2"
CompletionInterval="1000"
EnableCaching="true"
CompletionSetCount="20"
CompletionListCssClass="autocomplete_completionListElement"
CompletionListItemCssClass="autocomplete_listItem"
CompletionListHighlightedItemCssClass="autocomplete_highlightedListItem"
DelimiterCharacters=";, :"
ShowOnlyCurrentWordInCompletionListItem="true">
</cc2:AutoCompleteExtender>
</Template>
</cc1:MyRepeater>
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
namespace RelationalGridView.Web
{
public partial class MyRepeaterComplex : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//MyRepeater1.ItemPreRender += new WebGui.Extensions.MyRepeater.MyRepeaterItemPreRenderDelegate(MyRepeater1_ItemPreRender);
}
protected void MyRepeaterItemPrerender(object sender, WebGui.Extensions.MyRepeater.MyRepeaterItemEventArgs e)
{
TextBox tbx = (TextBox)e.Container.FindControl("TextBox1");
AutoCompleteExtender ace = (AutoCompleteExtender)e.Container.FindControl("AutoCompleteExtender1");
ScriptManager.GetCurrent(this).RegisterExtenderControl(ace, tbx);
}
}
}
MyRepeater的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Collections;
namespace WebGui.Extensions.MyRepeater
{
public delegate void MyRepeaterItemPreRenderDelegate(object sender, MyRepeaterItemEventArgs e);
public class MyRepeater: WebControl
{
List<Control> Containers;
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateContainer(typeof(MyRepeaterTemplateContainer))]
public ITemplate Template { get; set; }
public event MyRepeaterItemPreRenderDelegate ItemPreRender;
public MyRepeater()
{
RepeatCount = 0;
Containers = new List<Control>();
}
public int RepeatCount { get; set; }
protected override void OnPreRender(EventArgs e)
{
MyRepeaterItemEventArgs ex = new MyRepeaterItemEventArgs();
for (int i = 0; i < RepeatCount; i++)
{
MyRepeaterTemplateContainer container = new MyRepeaterTemplateContainer();
container.Page = Page;
Template.InstantiateIn(container);
if (ItemPreRender != null)
{
ex.Container=container;
ItemPreRender(this, ex);
}
Containers.Add(container);
}
}
protected override void Render(HtmlTextWriter writer)
{
foreach (Control ctrl in Containers)
{
ctrl.RenderControl(writer);
writer.WriteLine();
}
}
}
}
答案 0 :(得分:0)
您需要使用CreateChildControls方法,而不是在OnPreRender方法中实例化模板。此方法用于创建子控件。问题的原因是您的扩展程序在页面生命周期中被添加到控件集合中太晚,这就是无法注册的原因。
我可以建议使用Composite控件作为基本控件而不是WebControl。 Dino Esposito有一篇关于这个领域的非常好的文章:http://msdn.microsoft.com/en-us/library/aa479016.aspx。
还有一点需要注意:如果您创建继承自WebControl的自定义服务器控件,并希望同一命名容器(如页面等)中的两个实例具有不同的子控件ID,则需要使用INamingContainer接口标记自定义控件。可以在本文中找到更多信息:http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx