I am trying to make my own version of a repeater control. It is not a DataBoundControl; it won't be bound to a DataSource, DataSourceID, DataBind method etc etc. It has is a template nested inside it, and, a property called RepeatCount
, and it will repeat whatever is inside the template as specified by the afore-mentioned property.
However, if you add a textbox, and an autocomplete extender associated with it inside the template, the functionality of auto-completing is broken. Here is an image showing the spate of problems:
Notice the textbox ids generated. All I've added is a TextBox with
ID="TextBox1"
inside the template, but the same name/id got
repeated multiple times.
You can see that the textbox is visible. To understand why it is
visible, look in the code behind and view the ItemPreRender event
I've handled (on the aspx page). If I had not written code like that
I'd get an exception saying:
- However writing code as mentioned in pt2 doesn't get me anywhere. The
auto-complete functionality fails to work appropriately.
What could be the problem here? If this was properly put in a repeater control and made to work in a similar fashion it would work...
So what am I missing here?
Here are parts of the source code I am sharing:
aspx page
<%@ 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>
Apsx Code Behind:
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);
}
}
}
Code for 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();
}
}
}
}