Try removing the extender. Then add a ScriptReference to your ScriptManager (I didn't try this, but it would look like this: <asp:ScriptReference Assembly="AjaxControlToolkit" Name="AjaxControlToolkit.AlwaysVisibleControlBehavior.js") and then add a touch of javascript to hook it up like what I did below.
I ran into this error and I did a lot of research to try to find out what the problem was and how to fix it. The only thing that I came up with is that under any circumstance where the PreRender method isn't called on the extender control, this error would come up. The RegisterExtenderControl method MUST be called during the PreRender method, and the RegisterScriptDescriptors method is getting executed during the Render method. This is a problem because the PreRender method on the control isn't being called.
I also wanted to modify the functionality of the Always Visible Control extender so that the control would always have the same horizontal position, and never have less than the it's original vertical position. So I extracted the javascript code that I needed, removed the rest, and changed what I wanted. Regardless, this took care of both problems at once (got rid of the error, and let me alter the behavior).
In my user control, I have a ScriptManagerProxy followed by a small javascript codeblock like so:
<asp:ScriptManagerProxy ID="proxy" runat="server">
<Scripts>
<asp:ScriptReference Path="KeepTop.js" />
</Scripts>
</asp:ScriptManagerProxy>
<script type="text/javascript">
Sys.Application.add_load(function(sender, args) {
$create(Position.KeepTop, null, null, null, $get('<%= Me.FloatPanel.ClientId %>'));
});
</script> <asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel ID="FloatPanel" runat="server" Width="300px">
...
...
Here's the source code for that KeepTop.js file.
/// <reference name="MicrosoftAjax.js" />
Type.registerNamespace('Position');
Position.KeepTop = function(element) {
/// <param name="element" type="Sys.UI.DomElement" domElement="true">
/// The DOM element that is associated with
/// </param>
Position.KeepTop.initializeBase(this, [element]);
this._handler = null;
this._verticalOffset = Sys.UI.DomElement.getBounds(element).y;
}
Position.KeepTop.prototype = {
initialize : function()
{
Position.KeepTop.callBaseMethod(this, 'initialize');
var element = this.get_element();
if (!element) throw Error.invalidOperation("element required");
this._handler = Function.createDelegate(this, this._reposition);
// Attach the onScroll event handler
Sys.UI.DomEvent.addHandler(window, 'scroll', this._handler);
this._reposition();
},
dispose : function()
{
if (this._handler) {
Sys.UI.DomEvent.removeHandler(window, 'scroll', this._handler);
}
Position.KeepTop.callBaseMethod(this, 'dispose');
},
_reposition : function(eventObject)
{
/// <param name="eventObject" type="Sys.UI.DomEvent">
/// Event info
/// </param>
/// <returns />
var element = this.get_element();
if (!element) return;
var location = Sys.UI.DomElement.getLocation(element);
var scrollTop = 0;
if (document.documentElement && document.documentElement.scrollTop)
scrollTop = document.documentElement.scrollTop;
else
scrollTop = document.body.scrollTop;
location.y = scrollTop + this.get_verticalOffset();
Sys.UI.DomElement.setLocation(element, location.x, location.y);
},
get_verticalOffset : function() {
/// <value type="Number" integer="true">
/// Distance to the vertical edge of the browser in pixels from the same side of the target control. The default is the original vertical position of the element in pixels.
/// </value>
return this._verticalOffset;
},
set_verticalOffset : function(value) {
if (this._verticalOffset != value) {
this._verticalOffset = value;
this._reposition();
this.raisePropertyChanged('verticalOffset');
}
}
}
Position.KeepTop.registerClass('Position.KeepTop', Sys.UI.Control);
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
Sadly, that's as close to an answer that I've discovered so far. If I find a better way, I'll post it.