Showing posts with label programmatically. Show all posts
Showing posts with label programmatically. Show all posts

Wednesday, March 28, 2012

Programatically Adding an AutoCompleteExtender & AutoCompleteProperties

This is from the documentation:

To extend a text box with auto-completion behavior programmatically, add an AutoCompleteExtender control to your ASP.NET Web page, and use theServicePath andServiceMethod properties to specify the Web method that returns the item list. Then for each text box that you want to add the auto-completion behavior to,add anAutoCompleteProperties server control to theControls collection of the AutoCompleteExtender. The AutoCompleteProperities component enables you to specify the target control the extender should link to and to override the ServicePath and ServiceMode setting for individual controls.

So am I to understand that I add an AutoCompleteProperties instance to the AutoCompleteExtender.Controls collection?

When I try that I get this message in VS2005:

Value of type 'Microsoft.Web.UI.Controls.AutoCompleteProperties' cannot be converted to 'System.Web.UI.Control'.

hello.

well, you just need to add them as child elements of the control since it'll automaticatically parse those elements and add them to the targetproperties property.


...forgive me for my ignorance, but how exactly is that accomplished? Can you provide a brief example?

Thanks! :)


Dim autoComplete as New AutoCompleteExtender()
Dim props as New AutoCompleteProperties()
props.TargetControlID = "txt_suggestion"
props.ServiceURL = "/WebServices/Service.asmx"
props.ServiceMethod = "GetSuggestions"
autoComplete.TargetProperties.Add(props)
Page.Controls.add(autoComplete)

Hey that worked! Thanks!

I didn't know about the AutoCompleteExtender.TargetProperties.Add method, I was trying to add it to the controls collection of the AutoCompleteExtender.

FYI - The ServiceURL property in the above code is supposed to be ServicePath (at least in the July 06 release).

Programmatic client side initialization of HoverMenuPopup

I am trying to link a HoverMenuPopup to anchor tags on a page programmatically and I would like to implement something similar to the FAQ #13:
http://forums.asp.net/t/992919.aspx

This code is outdated now, and does not work.

How would it be written for the released version of the AJAX Control Toolkit?

Thank you,

Jeff

Hi Jeff,

Here is a sample made according to your requirements, please try it.

<%@. Page Language="C#" %><!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 id="Head1" runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager> <div> <input type="button" onclick="addHoverMenu();" value="Add Hovermenu to HyperLink" /><br /> <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="http://www.msdn.com">HyperLink</asp:HyperLink> <asp:Panel ID="Panel1" runat="server" Height="50px" Width="125px"> Item1<br /> Item2<br /> Item3<br /> Item4<br /> </asp:Panel> <script type="text/javascript"> function addHoverMenu() { $create(AjaxControlToolkit.HoverMenuBehavior, {"id":"Repeater1_ctl10_HoverMenuExtender1","popupElement":$get("<%= Panel1.ClientID%>")}, null, null, $get("<%= HyperLink1.ClientID%>")); } </script><div style="display:none;" >Controls in this div are used to import necessary javascripts. <asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton> <asp:Panel ID="Panel2" runat="server" Height="50px" Width="125px"> </asp:Panel> <ajaxToolkit:HoverMenuExtender ID="HoverMenuExtender1" PopupControlID="Panel2" runat="server" TargetControlID="LinkButton1"> </ajaxToolkit:HoverMenuExtender> </div> </div> </form></body></html>

That is what I was looking for Raymond. Now I will need to look into setting the popup location, timeout, etc.

Thank you,

Jeff


Raymond,

I've run into a bit of a snag with the popup. What I want to do is link a number of anchor tags to a single popup instance. When I use the logic of attaching behaviors to multiple anchors, certain events attached to the single popup cause the popup to jump between the anchor tags when I mouse over the popup (after hovering over a second anchor associated with the same popup).

What would you suggest I change in the below code to address this:

<%@. Page Language="C#" %>

<%@. Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %>
<%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<!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 id="Head1" runat="server">
<title>Hover Sample</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>

<script type="text/javascript">
function hover(element)
{
var behaviorName = "HoverMenuExtender_" + element.uniqueID;
var behavior = $find(behaviorName);
var popupElement = $get("<%= pnlHoverPopup.ClientID%>");

if (behavior == null)
{
behavior = $create(AjaxControlToolkit.HoverMenuBehavior, {"id":behaviorName, "popupElement":popupElement, PopDelay:750, OffsetX:-200, OffsetY:16}, null, null, element);
behavior.set_PopupPosition(AjaxControlToolkit.HoverMenuPopupPosition.Bottom);
}
}
</script>

<div>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean nisl justo, sagittis
id, tincidunt nec, euismod ac, turpis. Proin ante. Sed venenatis libero ac nisi.
Nunc varius ultrices velit. Donec vestibulum interdum ligula. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla facilisi.
Nunc vel ligula. In <a href="http://links.10026.com/?link=http://forums.asp.net/p/1167961/1956419.aspx#1956419#" onmouseover="return hover(this);">Internet</a> nisi
eget turpis. Nunc diam. Etiam congue ipsum. Proin vitae mauris et risus ultrices
vestibulum. Phasellus laoreet lectus quis augue. Vestibulum accumsan. Curabitur
sit amet eros eu justo rhoncus eleifend. Donec semper pharetra nibh. Pellentesque
habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Pellentesque habitant morbi tristique senectus et netus et <a href="http://links.10026.com/?link=http://forums.asp.net/p/1167961/1956419.aspx#1956419#" onmouseover="return hover(this);">
Internet</a> fames ac turpis.
</div>
<asp:Panel ID="pnlHoverPopup" runat="server" Style="visibility:hidden;background-color:#ccccff;width:300px; padding:10px;color:#000000;">
<h3>
Internet</h3>
A series of interconnected local, regional, national and international networks,
linked using the Internet Protocol. The Internet is accessible via telephony wires,
HFC networks and by satellite.
</asp:Panel>
<div style="display: none;">
Controls in this div are used to import necessary javascripts.
<asp:LinkButton ID="LinkButton1" runat="server">LinkButton</asp:LinkButton>
<asp:Panel ID="Panel2" runat="server" Height="50px" Width="125px">
</asp:Panel>
<ajaxToolkit:HoverMenuExtender ID="HoverMenuExtender1" PopupControlID="Panel2" runat="server"
TargetControlID="LinkButton1">
</ajaxToolkit:HoverMenuExtender>
</div>
</form>
</body>
</html>

Thank you,

Jeff

Programmatically add an Extender

I'm a huge newbie when it comes down to AJAX, ASP.NET and some more of the good stuff. I hope you don't mind me sticking around here ...

I've been playing around with de CustomDragDrop library provided by Omar Al Zabir. (http://www.codeproject.com/Ajax/MakingGoogleIG.asp)
I added some transparency while dragging and the ability to call a WebService or a WebMethod (on the Page) .

I've got a static example with a few div's which are draggable into other div's, registered as dropzone's.

Now, I want to makes this useable!
I've created a DataList and I want to programmaticaly add CustomFloatingBehavior to each DataListItem.
So in the event OnItemCreated, I make a new CustomFloatingBehaviorExtender and provide the necessary properties.
Finally I put my extender in the UpdatePanel and Update it.


There's just one thing I can't figure out ...
In the static version each draggable item has JS init handler looking like this:
Sys.Application.add_init(function() {
$create(CustomDragDrop.CustomFloatingBehavior, {"DragHandleID":"DragHandle","id":"WidgetFloatingBehavior"}, null, null, $get("DragItem"));
});


My dynamic version doesn't work yet, and it think the problem might be the above lines.
I should be able to programmatically add these for each DataListItem aswell.
Has anyone got anay suggestions?

Thanks in advance!

You'll find that dragdrop stuff is currently pretty poorly supported and you might be better off rolling your own.

Personally, I do drag-drop entirely on the client side (via $create(Sys.Preview.UI.FloatingBehavior...etc) calls), and I avoid UpdatePanels like the plague. As such, I'm not as clear on the UpdatePanel lifecycle and events as I should be to answer your question, but I suspect that the clientside init event is not fired by the updatepanel on partial postback. Consider isntead looking athttp://ajax.asp.net/docs/overview/PartialPageRenderingOverview.aspx and see if you can use that pagerequestmanage.add_pageLoaded() function (or one of the other member functions) to fire off a custom javascript that runs the $create() script on new draggable items.

programmatically add calendarextender

hey all,

is this possible to attach a calendarextender control to a textbox? i'm trying to build all my controls dynamically and i'm having problems with postback/async callback behavior. Mainly not understanding what's going on? anyone have any good references on how to do this? That is, build all controls dynamically with some ajax mixed in?

thanks,

rodchar

rodchar:

is this possible to attach a calendarextender control to a textbox? i'm trying to build all my controls dynamically and i'm having problems with postback/async callback behavior. Mainly not understanding what's going on? anyone have any good references on how to do this? That is, build all controls dynamically with some ajax mixed in?

You certainly can do that.

You will just have to create an instance of the calendarextender, assign it the textbox id to its targetcontrolID property. Also make sure this web page/user control has reference to the AJAX tool kit assembly

e.g.

//first add textbox dynamically and give it an IDTextBox myTextBox =new TextBox();myTextBox.ID ="txtCalendar";//now add the calendarExtendar and assign the targetcontrol IDAjaxControlToolkit.CalendarExtender myCalExt =new AjaxControlToolkit.CalendarExtender();myCalExt.TargetControlID = myTextBox.ID;//add both controls to the form/panel control collectionthis.Form1.Controls.Add(myTextBox);this.Form1.Controls.Add(myCalExt);
/

Programmatically adding a ConfirmButtonExtender

Hi,

I cannot get my ConfirmButtonExtender to work when I add it from the code behind.

A javascript page error occurs the page loads:

Line: 2829
Char:23
Error: Sys.ArgumentException: Value must not be null for Controls and Behaviors.
Parameter name: element
Code:0

---------------

Here is the code:

-- .asp snippet----

 <asp:ScriptManager ID="ScriptMan1" runat="server"> </asp:ScriptManager> <asp:Panel ID="Panel1" runat="server"> </asp:Panel> 

---.asp.cs snippet----

protected void Page_Load(object sender, EventArgs e) { Button button =new Button(); button.Text ="Click Me"; Panel1.Controls.Add(button); AjaxControlToolkit.ConfirmButtonExtender confirmDeleteExt =new AjaxControlToolkit.ConfirmButtonExtender(); confirmDeleteExt.TargetControlID = button.UniqueID; confirmDeleteExt.ConfirmText ="Are you sure?"; Panel1.Controls.Add(confirmDeleteExt); }

----------

It's nothing special, but what am I missing?!

I am dynamically building the page, so beginning with the button on the page is not an option (which works no problem).

Thanks!

Your code works fine on my computer.


OK,

Thanks for your reply, kipo, looking at it again it seems that the error only seems to occur when using a masterpage.

Does it still work for you if you put all of it into a masterpage?


I've tried to put your code in page which is using MasterPage and it doesn't work, so you were right - error is occuring only with MasterPage. But, you can achieve it with this code:

Button button = new Button();
button.Text = "Click Me";
button.ID = "button1";
Panel1.Controls.Add(button);

AjaxControlToolkit.ConfirmButtonExtender confirmDeleteExt = new AjaxControlToolkit.ConfirmButtonExtender();
confirmDeleteExt.TargetControlID = "button1";
confirmDeleteExt.ConfirmText = "Are you sure?";
Panel1.Controls.Add(confirmDeleteExt);


Excellent!Big Smile

Thanks a lot for your help!

I thought this problem was related to IDs, but is this a bug or is this by design?

Programmatically adding ASP.net User Control to UpdatePanel

Hi All, I got a real doozy here. I have read hundreds upon hundreds of forum posts and found numerous others who have replicated this problem, but have yet to find a solution. Through testing I have been able to find the cause of the problem, and will describe it here first textually and then through a code example.

The purpose of what I am trying to do is to create a postback-free web application through the use of ASP.net AJAX UpdatePanels and User Controls. When programmatically adding a User Control to a web page through a normal postback everything works fine. All the controls within the user control are registered properly in the page and any update panels included in the user control also work properly. HOWEVER, if instead of using a full postback you use an UpdatePanel and a partial page update of the UpdatePanel the controls do not get registered with the page and events from them do not fire (for instance, a button click event never hits the event breakpoint).

Because the very same user control works fine if loaded in a full postback or dynamically added from a namespace works fine, I can be relatively sure that it only is trouble when loading via a partial page update into an UpdatePanel. I load the control via the LoadConrol method and then add it to the page via a PlaceHolder control. Theoretically, adding the User Control to the PlaceHolder should register itself and it's controls and events with the page, but it does not.

The following code sample is a UpdatePanel-free page using a user control that works, later I will show the same code with an UpdatePanel that does not.

I think I need to figure out how to register the controls and their events with the page without going through a full page postback. Any suggestions??

This example works as expected:
Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
12 </div>
13 </form>
14</body>
15</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
1011public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 Control ctl = LoadControl("~/UserControlDemo.ascx");
16 ctl.ID ="UC1";
17this.UCPlaceHolder.Controls.Add(ctl);
18 }
19}

UserControlDemo.ascx:
1<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="UserControlDemo.ascx.cs" Inherits="UserControlDemo" %>2<asp:Button ID="Button1" runat="server" Text="Display from UC" OnClick="Button1_Click" /> <br />
3<br />
4<asp:Label ID="Content" runat="server" Text="Content"></asp:Label>

UserControlDemo.ascx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
1112public partialclass UserControlDemo : System.Web.UI.UserControl
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16 }
17protected void Button1_Click(object sender, EventArgs e)
18 {
19 Content.Text ="Content Changed.";
20 }
21}

Now, consider this variation, where instead of loading the control in the PageLoad event, you do so programmatically via a button Click event. This does not work as it cause a full postback which refreshes the placeholder. Viewstate does not seem to be working in this case. (uses the same user control as the previous example)

Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:Button ID="Button1" runat="server" Text="Load User Control" OnClick="Button1_Click" />
12 <br />
13 <br />
14 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
15 </div>
16 </form>
17</body>
18</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
1011public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 }
16protected void Button1_Click(object sender, EventArgs e)
17 {
18 Control ctl = LoadControl("~/UserControlDemo.ascx");
19 ctl.ID ="UC1";
20this.UCPlaceHolder.Controls.Add(ctl);
21 }
22}

To solve this postback problem, one would naturally want to use an UpdatePanel, like the following example. However this does not work as the controls do not seem to get registered with the page, and further nesting of user controls in UpdatePanels (to create a postback free app) are no better.

Default2.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>23<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
45<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>Untitled Page</title>
8</head>
9<body>
10 <form id="form1" runat="server">
11 <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
12 <div>
13 <asp:UpdatePanel ID="UpdatePanel2" runat="server">
14 <ContentTemplate>
15 <asp:Button ID="Button1" runat="server" Text="Load User Control into UpdatePanel" OnClick="Button1_Click" />
16 </ContentTemplate>
17 </asp:UpdatePanel>
18 <br />
19 <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
20 <ContentTemplate>
21 <asp:PlaceHolder ID="ContentPlaceHolder" runat="server"></asp:PlaceHolder>
22 </ContentTemplate>
23 <Triggers>
24 <asp:AsyncPostBackTrigger ControlID="Button1" />
25 </Triggers>
26 </asp:UpdatePanel>
27 </div>
28 </form>
29</body>
30</html>

Default2.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
1112public partialclass Default2 : System.Web.UI.Page
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
1617 }
18protected void Button1_Click(object sender, EventArgs e)
19 {
20 Control ctl = LoadControl("~/UserControlDemo.ascx");//loads into the page21 ctl.ID ="UC1";
22this.ContentPlaceHolder.Controls.Add(ctl);//adds to page control tree (or at least it should)23 }
24}

I know I can use the "visible" property of my controls to toggle them on and off a page to create a flicker free experience, however, my application is a database intensive app and I don't want the page running queries against the database unless I'm absolutely sure the user wants them. Rendering a 10 forms and keeping them hidden isn't a big deal, but running 10 queries that the user never wants to see is, otherwise I'd stick to that method, its works perfectly. Any suggestions? Or requests for clarification? Any help you can provide is much appreciated...thanks, Chris.

Chris, are you still working on this?

I've managed to get partial postbacks to fire events on the server from a button on a UserControl that was loaded as a result of a partial postback by an updatepanel.

Here's the code:

protected override void OnPreInit(EventArgs e){base.OnPreInit(e);if (this.Page.Request.Form["__UCTL"] !=null)this.ChangeControls(this.Page.Request.Form["__UCTL"].ToString(),null);elsethis.ChangeControls("Login","Login");}public void ChangeControls(String controlName, String controlTitle){ScriptManager.RegisterHiddenField(this,"__UCTL", controlName);this.host.ContentTemplateContainer.Controls.Clear();UserControl ctl = (UserControl)Page.LoadControl(CONTROL_DIRECTORY +"\\" + controlName +".ascx");ctl.ID = controlName;this.host.ContentTemplateContainer.Controls.Add(ctl);if (controlTitle !=null)this.host.Page.Title = controlTitle;}

I also created an Interface that has a method of ChangeControls with that signature and had my Page implement it so that my UserControls could get access to the method.


Hi Jason,

I figured out how to do it properly, you need to raise an event from the control and listen for it with the page or another control. The code to do so is also simpler than what you have. Check out this thread for more details: http://forums.asp.net/t/1123449.aspx

Feel free to msg me questions if you are confused.

-Chris

Programmatically adding ASP.net User Control to Partial Page Update / UpdatePanel

Hi All, I got a real doozy here. I have read hundreds upon hundreds offorum posts and found numerous others who have replicated this problem,but have yet to find a solution. Through testing I have been able tofind the cause of the problem, and will describe it here firsttextually and then through a code example.

Thepurpose of what I am trying to do is to create a postback-free webapplication through the use of ASP.net AJAX UpdatePanels and UserControls. When programmatically adding a User Control to a web pagethrough a normal postback everything works fine. All the controlswithin the user control are registered properly in the page and anyupdate panels included in the user control also work properly. HOWEVER,if instead of using a full postback you use an UpdatePanel and apartial page update of the UpdatePanel the controls do not getregistered with the page and events from them do not fire (forinstance, a button click event never hits the event breakpoint).

Becausethe very same user control works fine if loaded in a full postback ordynamically added from a namespace works fine, I can be relatively surethat it only is trouble when loading via a partial page update into anUpdatePanel. I load the control via the LoadConrol method and then addit to the page via a PlaceHolder control. Theoretically, adding theUser Control to the PlaceHolder should register itself and it'scontrols and events with the page, but it does not.

Thefollowing code sample is a UpdatePanel-free page using a user controlthat works, later I will show the same code with an UpdatePanel thatdoes not.

I think I need to figure out how to register thecontrols and their events with the page without going through a fullpage postback. Any suggestions??

This example works as expected:
Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
12 </div>
13 </form>
14</body>
15</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10
11public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 Control ctl = LoadControl("~/UserControlDemo.ascx");
16 ctl.ID ="UC1";
17this.UCPlaceHolder.Controls.Add(ctl);
18 }
19}

UserControlDemo.ascx:
1<%@dotnet.itags.org. Control Language="C#" AutoEventWireup="true" CodeFile="UserControlDemo.ascx.cs" Inherits="UserControlDemo" %>
2<asp:Button ID="Button1" runat="server" Text="Display from UC" OnClick="Button1_Click" /> <br />
3<br />
4<asp:Label ID="Content" runat="server" Text="Content"></asp:Label>

UserControlDemo.ascx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partialclass UserControlDemo : System.Web.UI.UserControl
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16 }
17protected void Button1_Click(object sender, EventArgs e)
18 {
19 Content.Text ="Content Changed.";
20 }
21}

Now,consider this variation, where instead of loading the control in thePageLoad event, you do so programmatically via a button Click event.This does not work as it cause a full postback which refreshes theplaceholder. Viewstate does not seem to be working in this case. (usesthe same user control as the previous example)

Default.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml">
5<head runat="server">
6 <title>Untitled Page</title>
7</head>
8<body>
9 <form id="form1" runat="server">
10 <div>
11 <asp:Button ID="Button1" runat="server" Text="Load User Control" OnClick="Button1_Click" />
12 <br />
13 <br />
14 <asp:PlaceHolder ID="UCPlaceHolder" runat="server"></asp:PlaceHolder>
15 </div>
16 </form>
17</body>
18</html>

Default.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Web;
5using System.Web.Security;
6using System.Web.UI;
7using System.Web.UI.WebControls;
8using System.Web.UI.WebControls.WebParts;
9using System.Web.UI.HtmlControls;
10
11public partialclass _Default : System.Web.UI.Page
12{
13protected void Page_Load(object sender, EventArgs e)
14 {
15 }
16protected void Button1_Click(object sender, EventArgs e)
17 {
18 Control ctl = LoadControl("~/UserControlDemo.ascx");
19 ctl.ID ="UC1";
20this.UCPlaceHolder.Controls.Add(ctl);
21 }
22}

Tosolve this postback problem, one would naturally want to use anUpdatePanel, like the following example. However this does not work asthe controls do not seem to get registered with the page, and furthernesting of user controls in UpdatePanels (to create a postback freeapp) are no better.

Default2.aspx:

1<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
2
3<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4
5<html xmlns="http://www.w3.org/1999/xhtml" >
6<head runat="server">
7 <title>Untitled Page</title>
8</head>
9<body>
10 <form id="form1" runat="server">
11 <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true"></asp:ScriptManager>
12 <div>
13 <asp:UpdatePanel ID="UpdatePanel2" runat="server">
14 <ContentTemplate>
15 <asp:Button ID="Button1" runat="server" Text="Load User Control into UpdatePanel" OnClick="Button1_Click" />
16 </ContentTemplate>
17 </asp:UpdatePanel>
18 <br />
19 <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
20 <ContentTemplate>
21 <asp:PlaceHolder ID="ContentPlaceHolder" runat="server"></asp:PlaceHolder>
22 </ContentTemplate>
23 <Triggers>
24 <asp:AsyncPostBackTrigger ControlID="Button1" />
25 </Triggers>
26 </asp:UpdatePanel>
27 </div>
28 </form>
29</body>
30</html>

Default2.aspx.cs:
1using System;
2using System.Data;
3using System.Configuration;
4using System.Collections;
5using System.Web;
6using System.Web.Security;
7using System.Web.UI;
8using System.Web.UI.WebControls;
9using System.Web.UI.WebControls.WebParts;
10using System.Web.UI.HtmlControls;
11
12public partialclass Default2 : System.Web.UI.Page
13{
14protected void Page_Load(object sender, EventArgs e)
15 {
16
17 }
18protected void Button1_Click(object sender, EventArgs e)
19 {
20 Control ctl = LoadControl("~/UserControlDemo.ascx");//loads into the page
21 ctl.ID ="UC1";
22this.ContentPlaceHolder.Controls.Add(ctl);//adds to page control tree (or at least it should)
23 }
24}

I knowI can use the "visible" property of my controls to toggle them on andoff a page to create a flicker free experience, however, my applicationis a database intensive app and I don't want the page running queriesagainst the database unless I'm absolutely sure the user wants them.Rendering a 10 forms and keeping them hidden isn't a big deal, butrunning 10 queries that the user never wants to see is, otherwise I'dstick to that method, its works perfectly. Any suggestions? Or requestsfor clarification? Any help you can provide is muchappreciated...thanks, Chris.

My suggestion is to not use an updatepanel for this. Google for ScottGu's blog on templating tricks; you can use a service to grab an ascx, feed it a datasource to populate the data then send the results to the page. use javascript to insert those results into the page DOM where needed, and code all your functionality in js or web methods of one form or another. It's a much cleaner / lower overhead way to do what you're trying to do anyway.


Hi Paul, I took a look at ScottGu blog, I believe this is the article you were referencing: http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx

Unfortunately this is not the solution I am looking for. By using this method I lose the main benefits of ASP.net: managed code, event based triggers, and the rest of the integrated features. I believe this method will cause the same problem, whatever I load into the page, the page won't be aware of it and no events will fire.

For now I am going to have to use postbacks, and I'll used the update panels for keeping things like sorting gridviews postback-less.

Thanks for the suggestion though!


I am having exactly the same problem

Can someone please help?

In similar situations before, I have used javascript and other hacks, but I feel reluctant to try to do it again. If we have a framework that can be used and can make work simpler, then It makes sense.

However, these kind of problems are frustrating, and I don't know what is the resolution. I am sure people mus thave encountered this before.

Can someone help?


This is more a dynamic controls problem than an AJAX problem.

When you dynamically add a control, you have to add it EVERY request. By moving it from PageLoad to Button_Click, you've stopped creating the control every request. You only create it if the button is pressed. That is why the events won't fire when you use controls within the user control -- because on the postback, the control doesn't even exist! The postback data is for a control that isn't in the control tree, because you didn't add it, because the event that adds it isn't firing again.

The technique to solve this is to utilize viewstate to remember that the control has been added, so that you can add it from the LoadViewState method. In your click handler, call a new method - LoadUserControl(). Define LoadUserControl to create and add the control, and to set a viewstate key, ViewState["LoadUserControl"] = true. Then override LoadViewState, and after calling base.LoadViewState, look for that viewstate key. If its true, call LoadUserControl().

New problem... Now its possible it will be added twice -- if you click the same button a 2nd time, LoadViewState will call it, and so will your button click handler. So add code to your button click handler to avoid creating it if its already loaded -- just check for the viewstate key.


Infinities...This is very interesting, thank you for your response! Unfortunately you lose me when you talk about overriding the LoadViewState. How would you modify the following code to accomplish what you are saying?

protected void Button_Click(object sender, EventArgs e)
{
Control ctl = LoadControl("~/userControl.ascx");
this.Panel1.Controls.Add(ctl);
}
Thanks!

Ok, that sounds promising. But, I don't think the situation would work still.

I have a gridView. In every row of a gridview, one of the cells contains a nested update panel. When the user clicks on a particular row, a user control dynamically gets added to the nested update panel. This works fine.

When I click on a particular button INSIDE this user control then the postback disappears, no events are triggered and nothing happens. The fact that the control probably does not exist makes sense because it justifies what happens, as in no events are fired.

However now this user control has values and data inside it, so when you are saying to load that control again, what happens to the value and the data, it looks like that data is lost. Is that not right?

Basically, in my situation AJAX cannot help. In the first place my user control should already have a viewstate in order to persist the value of data and state of the elements inside the user control. Since its viewstate is not stored, the "re-adding" will simply not work at all.


gsinha25:

However now this user control has values and data inside it, so when you are saying to load that control again, what happens to the value and the data, it looks like that data is lost. Is that not right?

No that is not right. The fact you are loading it again doesn't mean its data is lost. All controls are reloaded every request, even the statically declared ones. ViewState maintains itself through the framework, but it only maintains the data in the control, not the control itself.

gsinha25:

Basically, in my situation AJAX cannot help.

You would have the same problem if you were not using ajax. What you'd see is that the loaded user control would disappear after you click a button in it.

gsinha25:

In the first place my user control should already have a viewstate in order to persist the value of data and state of the elements inside the user control. Since its viewstate is not stored, the "re-adding" will simply not work at all.

ViewState is maintained for the control. All you have to do is make sure it exists every request. It will work, trust me.


I'm sure the formatting of this is going to be off, but here's the basic idea.

protected void Button_Click(object sender, EventArgs e)
{
LoadUserControl();
}
private void LoadUserControl()
{
Control ctl = LoadControl("~/userControl.ascx");
this.Panel1.Controls.Clear();
this.Panel1.Controls.Add(ctl);

 ViewState["Loaded"] = true;

}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);

 if (ViewState["Loaded"] != null)
LoadUserControl();
 }


Hi Infinities,

This is starting to make sense. I believe what you are talking about will work for my problem - in fact I often assumed it had something to do with the viewstate, however my knowledge and experience with it is limited. (I am new to C# and ASP.net, coming over from ColdFusion.) I am still a little confused on the the LoadViewState override. As I understand it, this event fires after the Init event in the lifecyle, and it's goal is to reload the user control if it has been added to the page. One question that pops up here, and may be what gsinha was referencing, does chages to the control also progress if it is reloading the control every time? For instance, if the user control is a gridview populated from a database and I have sorted and/or filtered it, would these sorts and filters be passed along as well?

Another question, when you assign the view state key in "ViewState[" "] = true" does it matter which key you use? And a final question, where is the savedState object coming from in the LoadViewState override?

Thanks again for your help!

P.S. I read your writeup at your website on the viewstate, I think i'll need to read it three or four more times before I can make sense of it all but amazing stuff, I love the attention to detail!


ChrisCicc:

As I understand it, this event fires after the Init event in the lifecyle, and it's goal is to reload the user control if it has been added to the page.

The general role of LoadViewState is to deserialize the control's share of the page's entire viewstate payload. Think of viewstate as just a bunch of data -- data which is associated with each control on the page. On a postback, that data is available to the control that owns it again, if it's still around that is. The role of the code I gave you is to recreate the control if it was remembered previously that it had been created.

ChrisCicc:

One question that pops up here, and may be what gsinha was referencing, does chages to the control also progress if it is reloading the control every time? For instance, if the user control is a gridview populated from a database and I have sorted and/or filtered it, would these sorts and filters be passed along as well?

Yes -- because what you have to understand is that all controls are reloaded every request. In fact, the page is completely reconstructed from the ground up every request. Remember request/response mechanism of the web is essentially a stateless process. ASP.NET and other frameworks create the feeling of statefulness through tricks like ViewState and Session state. ViewState is persisted across posts -- the controls are not. You create the control tree for the page by either statically declaring it with asp.net markup, or by dynamically creating the controls yourself. But either way, the controls start completely fresh and new every request. ViewState is then deserialized and injected into the controls, restoring them to the state they were on the last request.

ChrisCicc:

Another question, when you assign the view state key in "ViewState[" "] = true" does it matter which key you use?

No -- the idea is just to remember the fact that the control was loaded. Each control's viewstate is scoped to it, so there's no risk of using a key thats already in use by some other control.

ChrisCicc:

And a final question, where is the savedState object coming from in the LoadViewState override?

That is the deserialized viewstate associated with that specific control. The base implementation uses it to repopulate the keys stored in the ViewState statebag.


ChrisCicc:

P.S. I read your writeup at your website on the viewstate, I think i'll need to read it three or four more times before I can make sense of it all but amazing stuff, I love the attention to detail!

Thanks for reading :) I know it's quite long... but hopefully worth it.


It works!! Thanks a bundle! This solved the most important problem I had, which was loading the user control on to the page via an Update Panel. It does however bring up a few further questions that I was hoping you could help with!

First, how do I modify your code so that I can have multiple buttons load different UCs each while still using the LoadViewState override? The following code is my best attempt at it:

Instead of using the click event to call the LoadUserControl function, I did this:

  
protected void LinkButton_Click(object sender, EventArgs e)
{
MainBodyPanel.Controls.Clear();
Control ctl = LoadControl("UserControl.ascx");
MainBodyPanel.Controls.Add(ctl);

ViewState["Loaded"] =true;
}

And then in the override I did as you suggested, only added an addtional If statement for each button and control,
and sent it back to the click event function instead of the LoadUserControl so that each control could have its
own viewstate key.
While I can add new controls to the page, I cannot see them again once another control calls the .clear()
function an all that is left is the viewstate which then throws an error as it doesn't see the same control tree.
Is there a better way?
 
The second problem I have is I cannot get different user controls to communicate with each other. This is
apparent in two places. The first is I have a user control with a set of links. it is these links that call the
other user controls into the update panel dynamically. If I add the UserControl dynamically before the page
loads, the links can't see the container panel on the page. I tried using this.findControl("...").Controls.Add()
but that didn't work. So for now I have the links hard coded into the page instead being their own user control,
but it's really too complex to keep doing it that way, and it limits my nesting options.
Thanks again for any help u can provide! 
 

Ok... help me understand :) You have a bunch of links, which when one is clicked, you want to dynamically load a user control into a particular spot. Is that 'spot' different for each link? If you click on one link and then another are there supposed to now be 2 controls on the page or does the 2nd one replace the first?

I'll assume you want only 1 control at a time.

What you described sounds like it should work. I personally wouldn't explicitly call the event handler -- thats usually a bad idea. It won't cause any problems if you know what you're doing but its better design to have a 3rd method that they both call, which gives each method a clear distinct purpose (its generally bad if you have to think... who called this method?).

One think you should definitely do is give the User Control you load a particular ID. Make the ID based on something that will (1) be exactly the same every time and (2) be different for different user controls. So for example, clicking on Link1 might load UC1.ascx with ID "uc1", and clicking Link2 might load UC2.ascx with ID "uc2". The reason for this is.. well, when you dont specify an ID, any control that requires one (textboxes for example) will use an autogenerated one. But if you load controls differently on a postback than you did on the first request, the IDs wont necessarily be the same, causing problems. Assigning an ID avoids that. You shouldn't have been getting the exception you mentioned... try what I said and let me know. If you still get it, show me some code...

About your user control communication problem... I'm not following 100%. Where and when exactly are you calling FindControl, and what control are you trying to find? With controls whenever you find yourself trying to get two of them to talk directly to each other... well its usually a sign that you could improve your design a bit. The control should be self sufficient, it shouldn't be broken because something else on the page isnt just so. Rather than have the control talk to the other control, you can have it raise an event. The page then listens for the event and decides what to do with it (something which the original control doesn't much care about), which may be to push something into another control on the page (the origin of which that control doesn't much care about). Much less coupled that way.


"I'll assume you want only 1 control at a time." correct assumption. there is a panel placeholder that the controls get swapped in and out of.

I tried adding the ID as you suggested but the exception still came up. Here is the code as it currently stands:

1protected void ViewCustomerListLinkButton_Click(object sender, EventArgs e)2 {3 MainBodyPanel.Controls.Clear();4 Control ctl = LoadControl("~/UserControls/CustomersControls/CustomerList.ascx");5 ctl.ID ="CustList";6 MainBodyPanel.Controls.Add(ctl);78 ViewState["CustList"] =true;9 }1011protected void AddCustomerLinkButton_Click(object sender, EventArgs e)12 {13 MainBodyPanel.Controls.Clear();14 Control ctl = LoadControl("~/UserControls/CustomersControls/CustomerAdd.ascx");15 ctl.ID ="CustAdd";16 MainBodyPanel.Controls.Add(ctl);1718 ViewState["CustAdd"] =true;19 }2021protected override void LoadViewState(object savedState)22 {23base.LoadViewState(savedState);2425if (ViewState["CustList"] !=null)26 ViewCustomerListLinkButton_Click(null,null);2728if (ViewState["CustAdd"] !=null)29 ViewCustomerListLinkButton_Click(null,null);3031 }

The exception is thrown because when I click on a second link, it Clears the MainBodyPanel control list, and the viewstate is looking for the control list that includes the now removed control. I tried various ways I could think of to remove the viewstate but to no avail...

"What you described sounds like it should work. I personally wouldn'texplicitly call the event handler -- thats usually a bad idea. It won'tcause any problems if you know what you're doing but its better designto have a 3rd method that they both call, which gives each method aclear distinct purpose (its generally bad if you have to think... whocalled this method?)."

I couldn't figure out a way to do this. I was having each click event pass the url via the function call LoadUserControl("~/control.ascx") but I couldn't figure out how to have the loadviewstate override pass the url back when needed, so I did it as you see above.

About the communication problem, in more detail, the problem is actually with the code above. Right now that is in my pages code behind, if i make those links into a user control, and then add the control to the page with those functions in the controls code behind, it cannot see the container panel (which in this case is the MainBodyPanel). I tried using the find control method but it still couldn't see it. With the links and event handlers hard coded it works fine.

Thanks!


With this code, once you click on one of the buttons, that control will always be loaded. When you click on one button you need to 'clear' the viewstate key of the other, otherwise you'll be trying to load both controls all the time. Pretty sure that is why you are getting the error, too. Easier if you just use the same key with a different value.

About the event handler thing...

protected void Link1_Handler(object sender, EventArgs args) { Foo(); }
private void Foo() { /* load Foo, set ViewState["Loaded"] = 1 */ };

protected void Link2_Handler(object sender, EventArgs args) { Bar(); }
private void Bar() { /* load Bar, set ViewState["Loaded"] = 2 */ };

protected override void LoadViewState(object savedState) {
base.LoadViewState(savedState);

if(ViewState["Loaded"] == 1) {
Foo();
}
else if(ViewState["Loaded"] == 2) {
Bar();
}
}

You might be tempted to store the path to the actual UserControl in ViewState, that way you can just LoadControl(ViewState["Loaded"]) ... but, don't :) Treat ViewState like user input. Don't trust it. If you did it that way, the user could maniuplate viewstate in such a way that they could cause any user control in your site to load, rather than be restricted to the two you want.

Ok... so I'm still confused about your links problem. You have each link as a user control, and when clicked you want them to load their content into the parent? Controls should not modify their parent's controls. It would be better like I said, to have an event raised by the control. The page, which contains all these link controls, just hooks that event on each control and then loads the control into the appropriate place. Your FindControl probably isn't working because FindControl only finds controls within the current naming container. User controls are naming containers. So when you say, this.FindControl("foo") from within a UserControl, you're only looking for a control named "foo" WITHIN the user control, not higher. To go higher you have to call FindControl on a control thats higher. But you still have to be careful with naming containers. You could start at the page level with this.Page.FindControl("foo"), but that will only find controls named "foo" that are children of page or children of non-naming containers in page. Imagine if you had a user control that contained control with ID "foo", and then you put 5 of them on the page. Which would you expect Page.FindControl("foo") to find? Its ambiguous -- thats why it won't find ANY. Each Foo is within a naming container, so their actual IDs are "uc1$foo", "uc2$foo", etc (where uc1=id of user control 1). If you know for sure the control will be in a particular place (for you it sounds like in a master page), then go ahead and hard code that ID... but be warned, its a fragile way to do it. Another approach is to have your Page expose a "MasterContainer" property of type Control. The user controls can then just say ((MyPageType)this.Page).MasterContainer.Controls.Add(), and it will work so long as the control is on a page that inherits from "MyPage" (which, all of your pages could inherit from).Ad infinitum... lots of different ways to deal with it.

Programmatically Adding Controls and Events

Hi, I am trying to add several link buttons to a page programmatically with the following code:

int i;
int i;
for (i = 0; i < 60; i++)
{
LinkButton lnk = new LinkButton();
lnk.ID = "region" + i;
lnk.CssClass = "mystyle";
lnk.Click += new System.EventHandler(lnk_Click);

addContent.Controls.Add(lnk);

}


which adds them perfectly, however I also want to add an event handler to them all (the same event handler) which I had hoped to achieve by adding the ' lnk.Click += new System.EventHandler(lnk_Click);'
however when the link buttons are now clicked the page freezes, any suggestions?

All that is assigned on the onclick event is a write out to a label within an ajax.net update panel.

Any help would be appreciated, cheers Jon

I set this up in my dev environment and wa sunabel to duplictae it. Can you post more of your code... the ASP and the code behind to give us a better idea of whats going on.

I got the code working - for some reason the fact that the linkbuttons were placed inside a updatepanel and that the 'childrenastriggers' set to true seems to cause the slow down.

I think i know the problem but i am not sure how to solve it!

basically my onload function generates around 1500 linkbuttons in tiny squares within an update panel, each assigned a unique ID.

onclick of each button it posts its unique number to a textbox (temporarily so i can see if it is doing something) it takes around 60 seconds to do this when the 'childrenastriggers' is set to true.

When this is not set to true it performs it instantly, which is fine, however what I am trying to achieve that on click of the linkbutton it puts the number in the box, and changes the css of the linkbutton, updates so the user can see it has changed.

However the update panel is refreshing the generation of 1500 link buttons - which is causing the slow down.

Without the update panel refreshing, and if i cause a full postback the change is instant.

Any ideas on how to get around this but still achieve something similar.


Try and place your button generation code in the Page_Init event.


worked a treat, thank you!

Programmatically adding hoverbehavior

I'm trying to convert some declarative code to its programmatic equivalent. I have the following. Am I missing something?

<control targetElement="objectElement">
<behaviors>
<hoverBehavior unhoverDelay="500" hoverElement="popup">
<hover>
<setProperty target="popupBehavior" property="PositioningMode" value="Absolute" />
<setProperty target="popupBehavior" property="x" value="50" />
<setProperty target="popupBehavior" property="y" value="50" />
<invokeMethod target="popupBehavior" method="show" />
</hover>
<unhover>
<invokeMethod target="popupBehavior" method="hide" />
</unhover>
</hoverBehavior>
</behaviors>
</control>

// <control targetElement="objectElement">
var objectControl =new Web.UI.Control(objectElement);
objectControl.initialize();
var objectControlBehaviors = objectControl.get_behaviors();

// <hoverBehavior unhoverDelay="500" hoverElement="popup">
var hoverBehavior =new Web.UI.HoverBehavior();
hoverBehavior.set_unhoverDelay(500);
hoverBehavior.set_hoverElement(popup);
objectControlBehaviors.add(hoverBehavior);

// <setProperty target="popupBehavior" property="PositioningMode" value="Absolute" />
var action =new Web.SetPropertyAction();
action.set_target(popupBehavior);
action.set_property("PositioningMode");
action.set_value("Absolute");
hoverBehavior.hover.addAction(action);

// <setProperty target="popupBehavior" property="x" value="50" />
var action1 =new Web.SetPropertyAction();
action1.set_target(popupBehavior);
action1.set_property("x");
action1.set_value("50");
hoverBehavior.hover.addAction(action1);

// <setProperty target="popupBehavior" property="y" value="50" />
var action2 =new Web.SetPropertyAction();
action2.set_target(popupBehavior);
action2.set_property("y");
action2.set_value("50");
hoverBehavior.hover.addAction(action2);

// <invokeMethod target="popupBehavior" method="show" />
var action3 =new Web.InvokeMethodAction();
action3.set_target(popupBehavior);
action3.set_method("show");
hoverBehavior.hover.addAction(action3);

// <unhover>
var unhoverBehavior =new Web.UI.HoverBehavior();
objectControlBehaviors.add(unhoverBehavior);

// <invokeMethod target="popupBehavior" method="hide" />
var action4 =new Web.InvokeMethodAction();
action4.set_target(popupBehavior);
action4.set_method("hide");
unhoverBehavior.unhover.addAction(action4);

Any help appreciated...

Hi,

it seems that you missed to call the initialize() method of the HoverBehavior.

You are missing the "popupBehavior" target, which needs to be attached, with the "id" set to "popupBehavior" to the <behaviors> tag under the <control> reference that you want to "pop up." For example, if you are wanting the "objectElement" to pop up, you would change that control reference in the following way:

<control targetElement="objectElement">
<behaviors>
<popupBehavior id="popupBehavior" ..the rest of the properties... />
</behaviors>
</control>


I was desperately looking on how to do this... and finally, I found the way... you got me started, so this is how to do it:

var test = document.getElementById("test");var p = document.getElementById("p");var popup =new Sys.UI.Control( p );

popup.initialize();

var objectControl =new Sys.UI.HyperLink(test);

objectControl.initialize();

var objectControlBehaviors = objectControl.get_behaviors();var pb =new Sys.UI.PopupBehavior();

pb.setOwner( popup );

pb.set_parentElement( objectControl );

pb.set_positioningMode(

"TopRight" );var invoke =new Sys.InvokeMethodAction();

invoke.set_target(pb);

invoke.set_method(

"show");var invokeu =new Sys.InvokeMethodAction();

invokeu.set_target(pb);

invokeu.set_method(

"hide");var behavior =new Sys.UI.HoverBehavior();

behavior.setOwner( objectControl );

behavior.initialize();

behavior.hover.addAction( invoke );

behavior.unhover.addAction( invokeu );

objectControlBehaviors.add( behavior );


And actually, here is the final version:

function

setHover( link, domPopup )

{

var popup =new Sys.UI.Control( domPopup );

popup.initialize();

var objectControl =new Sys.UI.HyperLink( link );

objectControl.initialize();

controls[index] = objectControl;

index++;

var objectControlBehaviors = objectControl.get_behaviors();var pb =new Sys.UI.PopupBehavior();

pb.setOwner( popup );

pb.set_parentElement( link );

pb.set_positioningMode( Sys.UI.PositioningMode.Absolute );

pb.set_x( 45 );

pb.set_y( 0 );

var invoke =new Sys.InvokeMethodAction();

invoke.set_target(pb);

invoke.set_method(

"show");var invokeu =new Sys.InvokeMethodAction();

invokeu.set_target(pb);

invokeu.set_method(

"hide");var behavior =new Sys.UI.HoverBehavior();

behavior.setOwner( objectControl );

behavior.set_hoverElement( domPopup );

behavior.initialize();

behavior.hover.addAction( invoke );

behavior.hover.add( populatePanel );

behavior.unhover.addAction( invokeu );

objectControlBehaviors.add( behavior );

}

Additional notes:

The popup div has to specific position:absolute. This might be a bug since you do not have to do that with the declarative syntax.

If you are dynamically creating and destroying these, make sure to do something like:

function

destroy()

{

for(var i = 0; i < index; i++ )

{

var b = controls[i].get_behaviors();

b =

null;

}

index = 0;

}

(I'm sure the right thing is to destroy the objects, but this works for my demo in an hour)

Hope this helps...


I'm getting closer whoever started this I'm trying very hard to make danz stuff work.


I'm getting closer whoever started this I'm trying very hard to make danz stuff work. First post was better Danz


Here you go, tested on firefox and ie6:

function CreateHoverOptions(popup_id, parentid, behaviorid, delayMS)
{
var popup_element = getObj(popup_id);
var popup_control = new Sys.UI.Control($(popup_id));
var parent = new Sys.UI.Control($(parentid));
var PopOptions = new Sys.UI.PopupBehavior();

PopOptions.set_id(behaviorid);
PopOptions.set_parentElement(getObj(parentid));
PopOptions.set_positioningMode("TopLeft");
popup_control.get_behaviors().add(PopOptions);

var HoverOptions = new Sys.UI.HoverBehavior();
HoverOptions.set_unhoverDelay(delayMS);
HoverOptions.set_hoverElement(popup_element);
parent.get_behaviors().add(HoverOptions);

var hoverAction = new Sys.InvokeMethodAction();
hoverAction.set_target(PopOptions);
hoverAction.set_method("show");
HoverOptions.hover.addAction(hoverAction);

var unhoverAction = new Sys.InvokeMethodAction();
unhoverAction.set_target(PopOptions);
unhoverAction.set_method("hide");
HoverOptions.unhover.addAction(unhoverAction);

PopOptions.initialize();
HoverOptions.initialize();
popup_control.initialize();
parent.initialize();
}

HOW to USE:
1. call following method in pageLoad()
CreateHoverOptions("OPTIONS", "image4", "beh", 1000);

HTML:
<div>
<img id="image4" src="http://pics.10026.com/?src=../images/tlogo.gif" />
</div>

<div id="OPTIONS" style="visibility:hidden;display:none;">
<div style="background-color:Yellow;">
<a href="http://links.10026.com/?link=javascript: alert('delete this pic');">[x]</a>
<a href="http://links.10026.com/?link=#">[e]</a>
</div>
</div

Has anyone updated the above code to the latest Ajax beta 1 or beta 2 version??

Thanks, Greg Benoit

Programmatically adding multi DragPanelExtenders?

Hi;

First of all what I need is to have more then one dragable panels inside my page. DragAndDrop em, record their locations to the DB

I'm using this script that I found in asp.net forum to find the location:

<scripttype="text/javascript">
Sys.Application.add_load(dragSetup);
function dragSetup() {
var dragPanel = $find('dragPanelBehavior1');
dragPanel.add_propertyChanged(locationUpdatedHandler);// the handler would get the name of the property from the event args and if it is 'location' then do the right thing.
returnfalse; }

function locationUpdatedHandler(sender, eventargs) {
if(eventargs.get_propertyName() =='location') {
var dragPanel = $find('dragPanelBehavior1');
var label = $get('dragPanelLocation');
var loc = dragPanel.get_location()
label.innerHTML = loc;}
}
</script>

However because of this script I have in the webusercontrol whenever I add my second webusercontrol it returns an error because they both aims the same panel's dragPanelBehavior1.

I couldn't solve this problem, any help would be preciated.

Again what I actually need is more then one dragable panels containig a webusercontrol and that I can find the location.

Thanks in advance

Hi Kaan,

First, DragPanelExtender's BehavirID should be uniquej though they are in different WebUserControls which are located in the same page.

Secondly, in your situation, I think you should remove out the Sys.Application.add_load(dragSetup) and its related functions from WebUserControls to the page.

To get or set the Panel's location , we can also use

//get

var el = $find('DragPanelBID').get_element();
var newLocation = $common.getLocation(el);

//set

var finalLocation = new Sys.UI.Point(x,y);
$find('DragPanelBID').set_location(finalLocation);

Hope this help.

Best regards,

Jonathan

programmatically checking atlas update progress

Hi,

I was wondering if there's a way to check the status of atlas update panel through script? I want to write some scripts after the update panel complete its process of getting data from the server.

Thanks.

hello.

well, you can do that easilly by handling the propertychanged event of the _pagerequestmanager object. search this forum for _pageRequestManager and _inPostBack. you'll find 1 or 2 posts on how to do that (from xml-script and javascript).


Thanks Luis. I found my answer in one of the posts.

Programmatically Create AnimationExtender

I have not found any previous posts addressing this issue. I need to create an AnimationExtender programmatically from the code behind. Does anyone know how to do this? For instance using the example provided on the Toolkit page:

1<ajaxToolkit:AnimationExtender id="ace" runat="server" TargetControlID="btnHelp">2 <Animations>3 <OnLoad><OpacityAction AnimationTarget="info" Opacity="0" /></OnLoad>4 <OnClick>5 <Sequence>6 <StyleAction AnimationTarget="flyout" Attribute="display" Value="block"/>7 <Parallel AnimationTarget="flyout" Duration=".3" Fps="25">8 <Move Horizontal="150" Vertical="-50" />9 <Resize Width="260" Height="280" />10 <Color AnimationTarget="flyout" StartValue="#AAAAAA" EndValue="#FFFFFF" Property="style" PropertyKey="backgroundColor" />11 </Parallel>12 <ScriptAction Script="Cover($get('flyout'), $get('info'), true);" />13 <StyleAction AnimationTarget="info" Attribute="display" Value="block"/>14 <FadeIn AnimationTarget="info" Duration=".2"/>15 <StyleAction AnimationTarget="flyout" Attribute="display" Value="none"/>16 <StyleAction AnimationTarget="info" Attribute="height" value="auto" />17 <Parallel Duration=".5">18 <Color AnimationTarget="info" StartValue="#666666" EndValue="#FF0000" Property="style" PropertyKey="color" />19 <Color AnimationTarget="info" StartValue="#666666" EndValue="#FF0000" Property="style" PropertyKey="borderColor" />20 </Parallel>21 <Parallel Duration=".5">22 <Color AnimationTarget="info" StartValue="#FF0000" EndValue="#666666" Property="style" PropertyKey="color" />23 <Color AnimationTarget="info" StartValue="#FF0000" EndValue="#666666" Property="style" PropertyKey="borderColor" />24 <FadeIn AnimationTarget="btnCloseParent" MaximumOpacity=".9" />25 </Parallel>26 </Sequence>27 </OnClick>28 </Animations>29 </ajaxToolkit:AnimationExtender>30 <ajaxToolkit:AnimationExtender id="AnimationExtender1" runat="server" TargetControlID="btnClose">31 <Animations>32 <OnClick>33 <Sequence>34 <StyleAction AnimationTarget="info" Attribute="overflow" Value="hidden"/>35 <Parallel AnimationTarget="info" Duration=".3" Fps="15">36 <Scale ScaleFactor="0.05" Center="true" ScaleFont="true" FontUnit="px" />37 <FadeOut />38 </Parallel>39 <StyleAction AnimationTarget="info" Attribute="display" Value="none"/>40 <StyleAction AnimationTarget="info" Attribute="width" Value="250px"/>41 <StyleAction AnimationTarget="info" Attribute="height" Value=""/>42 <StyleAction AnimationTarget="info" Attribute="fontSize" Value="12px"/>43 <StyleAction AnimationTarget="btnCloseParent" Attribute="opacity" value="0" />44 <StyleAction AnimationTarget="btnCloseParent" Attribute="filter" value="alpha(opacity=0)" />4546 </Sequence>47 </OnClick>48 <OnMouseOver>49 <Color Duration=".2" StartValue="#FFFFFF" EndValue="#FF0000" Property="style" PropertyKey="color" />50 </OnMouseOver>51 <OnMouseOut>52 <Color Duration=".2" EndValue="#FFFFFF" StartValue="#FF0000" Property="style" PropertyKey="color" />53 </OnMouseOut>54 </Animations>55 </ajaxToolkit:AnimationExtender>

How would you create this AnimationExtender from a code behind? I am using VB.NET, but generally I have no problem reading and converting C# code.

You can add the Animation Extender programmatically like this

<script runat="server">
void Page_Load()
{
AjaxControlToolkit.AnimationExtender ace = new AjaxControlToolkit.AnimationExtender();
ace.TargetControlID = 'control id'

ace.Animations = 'the actual animation that has to appear'

Page.Controls.AddAt(0,ace);
}
</script>

For more information please look at this url

http://www.codeplex.com/AtlasControlToolkit/WorkItem/View.aspx?WorkItemId=7408



Sorry for the lateness of this reply. I figured out how to do it through the code behind. You basically just write the XML for the behaviors into a string builder then create a new Animation Extender and assing the XML to the .Animations property.


if possible, can you share the code?

thanks


It has been a while since I did this. I got it to work, but did not end up using it as you can only have a few on a page before it starts to really affect the load time of the page. Just to make things a little clearer, and please remeber I am pulling this from memory, sbScript contains the JS for positioning the popup. sbOpen contains the XML for the opening animation. I did not include the closing since it is a little redundant.

1Protected Sub Page_PreRender(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles Me.PreRender2Dim _aeOpenAs New AjaxControlToolkit.AnimationExtender3Dim sbOpenAs New StringBuilder4Dim sbScriptAs New StringBuilder5Dim _ibHelpAs New ImageButton67 sbScript.AppendLine("<script type=""text/javascript"" language=""javascript"">")8 sbScript.AppendLine(" function Cover(bottom, top, ignoreSize) {")9 sbScript.AppendLine(" var location = Sys.UI.DomElement.getLocation(bottom);")10 sbScript.AppendLine(" top.style.position ='absolute';")11 sbScript.AppendLine(" top.style.top = location.y +'px';")12 sbScript.AppendLine(" top.style.left = location.x +'px';")13 sbScript.AppendLine(" if (!ignoreSize) {")14 sbScript.AppendLine(" top.style.height = bottom.offsetHeight +'px';")15 sbScript.AppendLine(" top.style.width = bottom.offsetWidth +'px';")16 sbScript.AppendLine(" }")17 sbScript.AppendLine(" }")18 sbScript.AppendLine("</script>")19 Response.Write(sbScript.ToString)2021 _ibHelp.ID = "ibHelp"22 _ibHelp.OnClientClick = "return false;"23 _ibHelp.ImageUrl = "/admin/images/buttons/help.png"24 _ibHelp.ToolTip = "ClickFor Help"25 phAnimation.Controls.Add(_ibHelp)2627 sbOpen.Append("<OnLoad><OpacityAction AnimationTarget=""info")28 sbOpen.Append(Me.ID)29 sbOpen.AppendLine(""" Opacity=""0"" /></OnLoad>")3031 sbOpen.AppendLine("<OnClick>")32 sbOpen.AppendLine("<Sequence>")3334 sbOpen.Append("<ScriptAction Script=""Cover($get('")35 sbOpen.Append(_ibHelp.ClientID)36 sbOpen.Append("'), $get('flyout")37 sbOpen.Append(Me.ID)38 sbOpen.AppendLine("'));"" />")394041 sbOpen.Append("<StyleAction AnimationTarget=""flyout")42 sbOpen.Append(Me.ID)43 sbOpen.AppendLine(""" Attribute=""display"" Value=""block""/>")4445 sbOpen.Append("<Parallel AnimationTarget=""flyout")46 sbOpen.Append(Me.ID)47 sbOpen.AppendLine(""" Duration="".3"" Fps=""25"">")4849 sbOpen.AppendLine("<Move Horizontal=""150"" Vertical=""-50"" />")50 sbOpen.Append("<Resize Width300"" Height=""300"" />")5152'sbOpen.Append("<Color AnimationTarget=""flyout")53 'sbOpen.Append(Me.ID)54 'sbOpen.AppendLine(""" StartValue=""#AAAAAA"" EndValue=""#FFFFFF"" Property=""style"" PropertyKey=""backgroundColor"" />")55 'sbOpen.AppendLine("</Parallel>")5657 sbOpen.Append("<ScriptAction Script=""Cover($get('flyout")58 sbOpen.Append(Me.ID)59 sbOpen.Append("'), $get('info")60 sbOpen.Append(Me.ID)61 sbOpen.AppendLine("'), true);"" />")6263 sbOpen.Append("<StyleAction AnimationTarget=""info")64 sbOpen.Append(Me.ID)65 sbOpen.AppendLine(""" Attribute=""display"" Value=""block""/>")666768 sbOpen.Append("<FadeIn AnimationTarget=""info")69 sbOpen.Append(Me.ID)70 sbOpen.AppendLine(""" Duration="".2""/>")7172 sbOpen.Append("<StyleAction AnimationTarget=""flyout")73 sbOpen.Append(Me.ID)74 sbOpen.AppendLine(""" Attribute=""display"" Value=""none"" />")7576 sbOpen.Append("<StyleAction AnimationTarget=""info")77 sbOpen.Append(Me.ID)78 sbOpen.AppendLine(""" Attribute=""height"" Value=""auto""/>")7980 sbOpen.AppendLine("<Parallel Duration="".5"">")81 sbOpen.Append("<Color AnimationTarget=""info")82 sbOpen.Append(Me.ID)83 sbOpen.AppendLine(""" StartValue=""#666666"" EndValue=""#FF0000"" Property=""style"" PropertyKey=""color""/>")84 sbOpen.Append("<Color AnimationTarget=""info")85 sbOpen.Append(Me.ID)86 sbOpen.AppendLine(""" StartValue=""#666666"" EndValue=""#FF0000"" Property=""style"" PropertyKey=""borderColor""/>")87 sbOpen.AppendLine("</Parallel>")888990 sbOpen.AppendLine("<Parallel Duration="".5"">")91 sbOpen.Append("<Color AnimationTarget=""info")92 sbOpen.Append(Me.ID)93 sbOpen.AppendLine(""" StartValue=""#FF0000"" EndValue=""#666666"" Property=""style"" PropertyKey=""color""/>")94 sbOpen.Append("<Color AnimationTarget=""info")95 sbOpen.Append(Me.ID)96 sbOpen.AppendLine(""" StartValue=""#FF0000"" EndValue=""#666666"" Property=""style"" PropertyKey=""borderColor""/>")97 sbOpen.Append("<FadeIn AnimationTarget=""btnCloseParent")98 sbOpen.Append(Me.ID)99 sbOpen.AppendLine(""" MaximumOpacity="".9"" />")100 sbOpen.AppendLine("</Parallel>")101102 sbOpen.AppendLine("</Sequence>")103 sbOpen.AppendLine("</OnClick>")104105 _aeOpen.ID = "aeOpen"106 _aeOpen.TargetControlID = "ibHelp"107 _aeOpen.Animations = sbOpen.ToString108109 phAnimation.Controls.Add(_aeOpen)110End Sub

crLord, thanks for your reply.

here is what i have in my .ascx html code

ps: i want to put everything on the codebehind but not sure if that possible to do, can you please see my code and give your feedback?

thanks

here is my code:

<%@. Control Language="C#" AutoEventWireup="true" CodeFile="AJAXPopUp.ascx.cs" Inherits="usercontrols_AJAXPublicInfo" %><%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %><div style="width: 200px"><!-- Button used to launch the animation--> <asp:ImageButton ID="btnInfo" runat="server" OnClientClick="return false;" ImageUrl="~/images/popup_info.gif" AlternateText="Show Detail Information..." /> <div id="flyout" style="display: none; overflow: hidden; z-index: 2; background-color: #ffff66; border: solid 1px #D0D0D0;"></div><!-- Info panel to be displayed as a flyout when the button is clicked --> <div id="info" style="display: none; z-index: 2; opacity: 0; filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0); font-size: 12px; background-color: #ffffcc; padding: 5px; border-right: #999999 1px solid; border-top: #999999 1px solid; border-left: #999999 1px solid; border-bottom: #999999 1px solid;"> <div id="btnCloseParent" style="float: right; opacity: 0; filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);"> <asp:LinkButton ID="btnClose" runat="server" OnClientClick="return false;" Text="X" ToolTip="Close" Style="background-color: #666666; color: #FFFFFF; text-align: center; font-weight: bold; text-decoration: none; border: outset thin #FFFFFF; padding: 5px;" /> </div> <div style="width: 300px"><!-- BEGIN: Here you can place your content. --> <table id="tblPublicInfo" border="1" style="width: 320px; background-color: AntiqueWhite"> <tr> <td> <b> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </b> </td> </tr> </table><!-- END: of the content. --> </div> </div> <script type="text/javascript" language="javascript"> // Move an element directly on top of another element (and optionally // make it the same size). // The location of the popup can be set in here. function Cover(bottom, top, ignoreSize) { var location = Sys.UI.DomElement.getLocation(bottom); top.style.position = 'absolute'; top.style.top = location.y + 'px'; top.style.left = location.x + 'px'; if (!ignoreSize) { top.style.height = bottom.offsetHeight + 'px'; top.style.width = bottom.offsetWidth + 'px'; } } </script> <ajaxToolkit:AnimationExtender ID="OpenAnimation" runat="server" TargetControlID="btnInfo"> <Animations> <OnClick> <Sequence> <%-- Disable the button so it can't be clicked again --%> <EnableAction Enabled="false" /> <%-- Position the wire frame on top of the button and show it --%> <ScriptAction Script="Cover($get('AJAXPopUp1_btnInfo'), $get('flyout'));" /> <StyleAction AnimationTarget="flyout" Attribute="display" Value="block"/> <%-- Move the wire frame from the button's bounds to the info panel's bounds --%> <Parallel AnimationTarget="flyout" Duration=".3" Fps="25"> <Move Horizontal="150" Vertical="-10" /> <Resize Width="300" /> <Color PropertyKey="backgroundColor" StartValue="#AAAAAA" EndValue="#FFFFFF" /> </Parallel> <%-- Move the info panel on top of the wire frame, fade it in, and hide the frame --%> <ScriptAction Script="Cover($get('flyout'), $get('info'), true);" /> <StyleAction AnimationTarget="info" Attribute="display" Value="block"/> <FadeIn AnimationTarget="info" Duration=".2"/> <StyleAction AnimationTarget="flyout" Attribute="display" Value="none"/> <StyleAction AnimationTarget="info" Attribute="filter" Value="progid:DXImageTransform.Microsoft.Shadow(direction=140,color=#666666,strength=4);"/> <%-- Flash the text/border red and fade in the "close" button --%> <Parallel AnimationTarget="info" Duration=".1"> <%-- PropertyKey="color" StartValue="#666666" EndValue="#FF0000" />--%> <Color PropertyKey="borderColor" StartValue="#666666" EndValue="#FF0000" /> </Parallel> <Parallel AnimationTarget="info" Duration=".1"> <%-- PropertyKey="color" StartValue="#FF0000" EndValue="#666666" />--%> <Color PropertyKey="borderColor" StartValue="#FF0000" EndValue="#666666" /> <FadeIn AnimationTarget="btnCloseParent" MaximumOpacity=".9" /> </Parallel> </Sequence> </OnClick> </Animations> </ajaxToolkit:AnimationExtender> <ajaxToolkit:AnimationExtender ID="CloseAnimation" runat="server" TargetControlID="btnClose"> <Animations> <OnClick> <Sequence AnimationTarget="info"> <%-- Shrink the info panel out of view --%> <StyleAction Attribute="overflow" Value="hidden"/> <Parallel Duration=".3" Fps="15"> <Scale ScaleFactor="0.05" Center="true" ScaleFont="true" FontUnit="px" /> <FadeOut /> </Parallel> <%-- Reset the sample so it can be played again --%> <StyleAction Attribute="display" Value="none"/> <StyleAction Attribute="width" Value="300px"/> <StyleAction Attribute="height" Value=""/> <StyleAction Attribute="fontSize" Value="12px"/> <OpacityAction AnimationTarget="btnCloseParent" Opacity="0" /> <%-- Enable the button so it can be played again --%> <EnableAction AnimationTarget="AJAXPopUp1_btnInfo" Enabled="true" /> </Sequence> </OnClick> <OnMouseOver> <Color Duration=".2" PropertyKey="color" StartValue="#FFFFFF" EndValue="#FF0000" /> </OnMouseOver> <OnMouseOut> <Color Duration=".2" PropertyKey="color" StartValue="#FF0000" EndValue="#FFFFFF" /> </OnMouseOut> </Animations> </ajaxToolkit:AnimationExtender> </div>

what isphAnimation?


My control was done in the code behind almost exclusively. I only had design elements in the .ascx. phAnimation is a PlaceHolder so I could add the controls. Here is my .ascx file. There are some things that were refernced for various reasons in my code behind like"lblHelpItemTitle" but I did include them in the above code for brevity. All they are, are controls tied to public properties of the control so I can assign their values based on what I wanted in that particular instance. Also the script code should only be added once to the page, but that should be fairly easy now with the new stuff for registering JS in 2.0. Response.Write is probably not the way to go anymore, but it sloved the problem then. I had orginally had a public property that was a boolean telling me if this was the first instance of the control on the page and if it was I included the script.

1<%@. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>23 <div>4 <div id="flyout<%=Me.ID%>" style="z-index:2;display: none; border: solid 1px #D0D0D0; background-color: #FFFFFF;overflow:hidden;"> </div>5 <div id="info<%=Me.ID%>" style="z-index:2;display: none; font-size: 12px; border: solid 1px #CCCCCC; background-color: #FFFFFF; width: 260px;">6 <div class="HelpItemTitleBar">7 <div class="HelpItemTitle">8 <asp:Label ID="lblHelpItemTitle" runat="server" />9 </div>10 <div class="HelpItemClose" id="btnCloseParent<%=Me.ID%>">11 <asp:LinkButton id="lbClose" runat="server" OnClientClick="return false;" Text="X" ToolTip="Close" />12 </div>13 </div>14 <div class="HelpItemText">15 <asp:Label ID="lblHelpText" runat="server" />16 </div>17 </div>18 </div>19 <asp:PlaceHolder id="phAnimation" runat="server" />

just to understand the code, i have implement your code in my test page and no errors found and why i run the page here is what i got:

Invalid Animation definition for TargetControlID="ibHelp": Name cannot begin with the '0' character, hexadecimal value 0x30. Line 1, position 82.

_aeOpen.Animations = sbOpen.ToString(); <<<<<<error

also i replace:
//Response.Write(sbScript.ToString);
this.Page.ClientScript.RegisterClientScriptBlock(GetType(),"OnClick", sbScript.ToString());

here is the complete code for your reference:

<%@.ControlLanguage="C#"AutoEventWireup="true"CodeFile="WebUserControl.ascx.cs"Inherits="usercontrols_WebUserControl" %><%@.RegisterAssembly="AjaxControlToolkit"Namespace="AjaxControlToolkit"TagPrefix="ajaxToolkit" %>

<div>

<divid="flyout<%=this.ID%>"style="z-index:2;display: none; border: solid 1px #D0D0D0; background-color: #FFFFFF;overflow:hidden;"></div>

<divid="info<%=this.ID%>"style="z-index:2;display: none; font-size: 12px; border: solid 1px #CCCCCC; background-color: #FFFFFF; width: 100px; height: 34px;">

<divclass="HelpItemTitleBar">

<divclass="HelpItemTitle">

<asp:LabelID="lblHelpItemTitle"runat="server"/>

</div>

<divclass="HelpItemClose"id="btnCloseParent<%=this.ID%>">

<asp:LinkButtonid="lbClose"runat="server"OnClientClick="return false;"Text="X"ToolTip="Close"/>

</div>

</div>

<divclass="HelpItemText">

<asp:LabelID="lblHelpText"runat="server"/>

</div>

</div>

</div>

<asp:PlaceHolderid="phAnimation"runat="server"/>

code behind:

using System;using System.Data;using System.Configuration;using System.Collections;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Text;public partialclass usercontrols_WebUserControl : System.Web.UI.UserControl{protected override void Render(HtmlTextWriter writer) { AjaxControlToolkit.AnimationExtender _aeOpen =new AjaxControlToolkit.AnimationExtender(); StringBuilder sbOpen =new StringBuilder(); StringBuilder sbScript =new StringBuilder(); ImageButton _ibHelp =new ImageButton(); sbScript.AppendLine("<script type='text/javascript' language='javascript'>"); sbScript.AppendLine(" function Cover(bottom, top, ignoreSize) {"); sbScript.AppendLine(" var location = Sys.UI.DomElement.getLocation(bottom);"); sbScript.AppendLine(" top.style.position = 'absolute';"); sbScript.AppendLine(" top.style.top = location.y + 'px';"); sbScript.AppendLine(" top.style.left = location.x + 'px';"); sbScript.AppendLine(" if (!ignoreSize) {"); sbScript.AppendLine(" top.style.height = bottom.offsetHeight + 'px';"); sbScript.AppendLine(" top.style.width = bottom.offsetWidth + 'px';"); sbScript.AppendLine(" }"); sbScript.AppendLine(" }"); sbScript.AppendLine("</script>");//Response.Write(sbScript.ToString);this.Page.ClientScript.RegisterClientScriptBlock(GetType(),"OnClick", sbScript.ToString()); _ibHelp.ID ="ibHelp"; _ibHelp.OnClientClick ="return false;"; _ibHelp.ImageUrl ="/admin/images/buttons/help.png"; _ibHelp.ToolTip ="Click For Help"; phAnimation.Controls.Add(_ibHelp); sbOpen.Append("<OnLoad><OpacityAction AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Opacity='0' /></OnLoad>"); sbOpen.AppendLine("<OnClick>"); sbOpen.AppendLine("<Sequence>"); sbOpen.Append("<ScriptAction Script='Cover($get('"); sbOpen.Append(_ibHelp.ClientID); sbOpen.Append("'), $get('flyout"); sbOpen.Append(this.ID); sbOpen.AppendLine("'));' />"); sbOpen.Append("<StyleAction AnimationTarget='flyout"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Attribute='display' Value='block'/>;"); sbOpen.Append("<Parallel AnimationTarget='flyout"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Duration='.3' Fps='25'>"); sbOpen.AppendLine("<Move Horizontal='150' Vertical='-50' />"); sbOpen.Append("<Resize Width300' Height='300' />");//'sbOpen.Append("<Color AnimationTarget='flyout") //'sbOpen.Append(Me.ID) //'sbOpen.AppendLine('" StartValue='#AAAAAA' EndValue='#FFFFFF' Property='style' PropertyKey='backgroundColor' />") //'sbOpen.AppendLine("</Parallel>") sbOpen.Append("<ScriptAction Script='Cover($get('flyout"); sbOpen.Append(this.ID); sbOpen.Append("'), $get('info"); sbOpen.Append(this.ID); sbOpen.AppendLine("'), true);' />"); sbOpen.Append("<StyleAction AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Attribute='display' Value='block'/>"); sbOpen.Append("<FadeIn AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Duration='.2'/>"); sbOpen.Append("<StyleAction AnimationTarget='flyout"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Attribute='display' Value='none' />"); sbOpen.Append("<StyleAction AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" Attribute='height' Value='auto'/>"); sbOpen.AppendLine("<Parallel Duration='.5'>"); sbOpen.Append("<Color AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" StartValue='#666666' EndValue='#FF0000' Property='style' PropertyKey='color'/>"); sbOpen.Append("<Color AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" StartValue='#666666' EndValue='#FF0000' Property='style' PropertyKey='borderColor'/>"); sbOpen.AppendLine("</Parallel>"); sbOpen.AppendLine("<Parallel Duration='.5'>"); sbOpen.Append("<Color AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" StartValue='#FF0000' EndValue='#666666' Property='style' PropertyKey='color'/>"); sbOpen.Append("<Color AnimationTarget='info"); sbOpen.Append(this.ID); sbOpen.AppendLine(" StartValue='#FF0000' EndValue='#666666' Property='style' PropertyKey='borderColor'/>"); sbOpen.Append("<FadeIn AnimationTarget='btnCloseParent"); sbOpen.Append(this.ID); sbOpen.AppendLine(" MaximumOpacity='.9' />"); sbOpen.AppendLine("</Parallel>"); sbOpen.AppendLine("</Sequence>"); sbOpen.AppendLine("</OnClick>"); _aeOpen.ID ="aeOpen"; _aeOpen.TargetControlID ="ibHelp"; _aeOpen.Animations = sbOpen.ToString(); phAnimation.Controls.Add(_aeOpen); }}

Simple mistake. When you did the conversion you did not carry over the closing quote of some of the fields. For Example you have:

sbOpen.Append("<OnLoad><OpacityAction AnimationTarget='info");
sbOpen.Append(this.ID);
sbOpen.AppendLine(" Opacity='0' /></OnLoad>");

And It Should Be:

sbOpen.Append("<OnLoad><OpacityAction AnimationTarget='info");
sbOpen.Append(this.ID);
sbOpen.AppendLine("' Opacity='0' /></OnLoad>");

It is hard to see, but I added a closing quote before Opacity.


One more thing. If you plan to use more than one of these on any given page you will want to wrap the RegisterClientScript inside a conditional checking IsClientScriptRegistered.


thank you so much

one last question.

i'm planning to use the same usercontrol more then one in page

you mean this code should be wrap? like this?

if(!Page.IsClientScriptRegistered("myscript"))
{
sbScript.AppendLine("<script type='text/javascript' language='javascript'>");
sbScript.AppendLine(" function Cover(bottom, top, ignoreSize) {");
sbScript.AppendLine(" var location = Sys.UI.DomElement.getLocation(bottom);");
sbScript.AppendLine(" top.style.position = 'absolute';");
sbScript.AppendLine(" top.style.top = location.y + 'px';");
sbScript.AppendLine(" top.style.left = location.x + 'px';");
sbScript.AppendLine(" if (!ignoreSize) {");
sbScript.AppendLine(" top.style.height = bottom.offsetHeight + 'px';");
sbScript.AppendLine(" top.style.width = bottom.offsetWidth + 'px';");
sbScript.AppendLine(" }");
sbScript.AppendLine(" }");
sbScript.AppendLine("</script>");
//Response.Write(sbScript.ToString);
this.Page.ClientScript.RegisterClientScriptBlock(GetType(),"myscript", sbScript.ToString());

}

.


Yes. Otherwise you will get an error. Also I do not know if the AJAX toolkit has been improved in the latest version, but when I was using it it seemed that it added the animation scripts for each instance and after about 20 or so of these controls on a page the load time really slowed down. I would be interested to here how you fair if you do many on one page.


speed to me looks like good, i did not put any stuffs in it. may be.

but after implementingIsClientScriptRegistered i'm still getting the same data of a previous a previous and its not throwing me any error.

any idea?

i change the above code to something like this but still same problem:

if (!this.Page.ClientScript.IsClientScriptBlockRegistered("rb-popup"))
{
this.Page.ClientScript.RegisterClientScriptBlock("rb-popup","js/JScript.js"
}


I don't understand the problem. Are you saying you have multiple controls but with the same data over and over? If so post the control code and the code for the page calling and I will see if I can find the problem.