Animating an Asp.Net Ajax Control Extender
Author: Fredrik Kalseth
7. December 2007 22:14
Earlier this year, I wrote a blog post describing how to develop a context menu control extender using the Asp.Net Ajax control toolkit. It was a fairly basic extender, allowing you to specify a context area and an associated control that should be displayed when the user right-clicked inside that area. In this post I’ll go back and enhance the extender with support for animating the context menu.
What I want to accomplish with the end result, is the ability to write markup similar to the following:
<idc:ContextMenuExtender ID="_cme" runat="server" ContextMenuControlID="_contextMenu" TargetControlID="_contextArea"> <Animations> <OnShow> <FadeIn Duration="0.25" /> </OnShow> <OnHide> <FadeOut Duration="0.25" /> </OnHide> </Animations> </idc:ContextMenuExtender>
If you’ve used any of the control extenders in the Ajax toolkit like the PopupControlExtender or UpdatePanelAnimationExtender, I’m sure you’ve seen that Animations tag before. It basically allows us to set up one or more storyboards for animations that should trigger on certain events – in the example above, applying a short FadeIn animation when the context menu is shown, and a short FadeOut animation when it is hidden.
The AnimationExtenderControlBase
Originally, my ContextMenuExtender inherited from the ExtenderControlBase class. The first step towards adding support for animations, is changing this to the AnimationExtenderControlBase, which will give me all the leverage I need to easily add animation support to my extender. This new base class has a few members that I’m interested in – there’s the Animations property, and the SetAnimation and GetAnimation methods. As you see from the markup above, the Animations property is the one that we’ll use to set up the storyboard for animations. The cool thing about this, is that it then automatically supports all the pre-built animation types that the toolkit contains – go take a look at the documentation to learn more about animations. The only thing we need to do to make it work, is to set up the different events that we want to support animation – in our case, they’re OnShow and OnHide. We do this by adding similarly named properties on our extender:
public Animation OnShow { get { return GetAnimation(ref _onShow, "OnShow"); } set { SetAnimation(ref _onShow, "OnShow", value); } } private Animation _onHide; public Animation OnHide { get { return GetAnimation(ref _onHide, "OnHide"); } set { SetAnimation(ref _onHide, "OnHide", value); } }
As you can see, these are decorated with the ExtenderControlProperty attribute to signal that I want the values they get set to, to be transported to the client-side component. Notice also that I’ve used the ClientPropertyName to change the client-side target property – I’m telling the toolkit to map the server-side property OnShow/OnHide to the client-side property onShowJson/onHideJson (or rather, the set_onShowJson/set_onHideJson and get_onShowJson/get_onHideJson methods, as JavaScript has no concept of properties).
That’s it for the server-side changes – the real stuff happens client-side, after all.
Animate Me
Our client-side stuff is defined in the ContextMenuBehavior object. The first thing we do, is to add the client-side properties that we told the server-side component to map the server-side OnShow and OnHide properties to:
get_onShowJson : function() { return this._onShowJson; }, set_onShowJson : function(value) { this._onShowJson = value; }, get_onHideJson : function() { return this._onHideJson; }, set_onHideJson : function(value) { this._onHideJson = value; }
Now, recall that the Animations property on the server-side extender control was just a string – so our _onShowJson and _onHideJson fields will just end up holding string representations of the animations – incidentally in a JSON format. We can use these strings to create AjaxControlToolkit.Animation objects, and we’ll do that in the initialize method of the component:
initialize : function() { Iridescence.Ajax.ContextMenuBehavior.callBaseMethod(this, 'initialize'); // other stuff removed for brevity... if(this._onShowJson) { this._onShowAnim = $AA.buildAnimation(this._onShowJson, this._menuElement); } if(this._onHideJson) { this._onHideAnim = $AA.buildAnimation(this._onHideJson, this._menuElement); } }
Now, if the any animations were specified, we’ll have them parsed into actual Animation objects ($AA is an alias for AjaxControlToolkit.Animation) in our component, and set to target the context menu (stored in the _menuElement field), ready to be triggered whenever the context menu is shown or hidden. To trigger them, we need to modify the showMenu and hideMenu methods of the ContextMenuBehavior prototype slightly:
showMenu : function(x,y) { // set flags this._menuVisible = true; this._menuJustShown = true; this._menuElement.style.left = x + 'px'; this._menuElement.style.top = y + 'px'; this._menuElement.style.display = ''; if(this._onHideAnim) { // if the hide animation is currently running, stop it this._onHideAnim.stop(); } if(this._onShowAnim) { this._onShowAnim.play(); } }
Most of this method is the same original – the only difference is that if there’s an OnShow animation specified, we start playing it, first ensuring that any OnHide animation currently playing is stopped.
hideMenu : function() { if(this._onShowAnim) { // if show anim is currently running, stop it this._onShowAnim.stop(); } if(this._onHideAnim) { this._onHideAnim.play(); } else { this._hideMenuCore(); } this._menuVisible = false; }
The hideMenu method is much the same – if there’s an OnHide animation we start playing it, first ensuring that any OnShow animation currently playing is stopped.
Play With Me
That was a very quick guide to adding support for animations in an Asp.Net Ajax Control Extender. You can read more about using animations over at the Asp.Net Ajax Control Toolkit website.
If you want to play around with the ContextMenuExtender, click here to download a Visual Studio 2008 solution including the source code, and an example project which shows a few usage scenarios of the extender. Feel free to use and abuse it to your hearts content 🙂
Comments
This post is also available in: English
10/11/2008 8:13:24 AM
Iam working asp.net 2.0 I have used AnimationExtedet but it should not any onclick events or sequence tags with in animation tag.please replay that quation.
trimurthy