ContextMenu - exposing and handling events
The ContextMenu is now code complete and I'm running through the code adding the appropriate Xml comment sections for when I produce the .chm file for the assembly. My aim is to have a Comment, Remark and Sample for each public member within the assembly.
Getting the IPostBackEventHandler
working was a snap - that's the interface you must implement if you want to be able to handle postback events from the client. Within your control, you basically call GetPostBackEventReference
on the Page
which will return the function call to invoke in the client to participate in the postback architecture. In the case of the ContextMenu, I did this:
' Build the postback script block Dim scriptStrng As String = "<script language='javascript' type='text/javascript'>" & VbCrLf scriptStrng &= "PostbackItemArray[" & Me.ClientId & "] = '" & _ Me.Page.GetPostBackEventReference(Me, "@menuResult@") & "'" & vbCrLf scriptStrng &= "</script>" ' Emit it into the page Me.Page.RegisterClientScriptBlock(mScriptKey & "_" & Me.ClientID, scriptStrng)
When it's sent to the client, it would look something like this:
"__doPostBack('Contextmenu2','@menuResult@')"
Which means that, when it's time to generate a postback, I simply replace the string "@menuResult@" with a string which represents some EventArgs information and eval
the entire string. That calls the ASP.NET generated __doPostBack function in the client passing in the identity of the control which invoked the callback and the event arguments. Here's how I do that...
// optional third argument... if present, value will be stored in value __ContextMenuPostBack function MarkItUp_ContextMenu_HandleItemClick( clickedItem, callback ) { MarkItUp_ContextMenu_Menu.Hide(); if( MarkItUp_ContextMenu_HandleItemClick.arguments.length == 2 && callback.length > 0 ) { // handle in the client var args = new MenuItemClickedEventArgs( clickedItem.commandArgument ) ; callback( clickedItem, args ) ; // callback is a function pointer to the client handler }else{ // handle on the server. // Generate a postback by doing eval on the __doPostBack string eval( MarkItUp_ContextMenu_Menu.PostBackScript.replace( "@menuResult@", clickedItem.commandArgument ) ); } }
I can now handle the postback either in the client or on the server - depending on where I've nominated to handle it - using the EventArgs information; which is identical in both:
// JAVASCRIPT CLIENT-SIDE HANDLER EXAMPLE function MyOnClickHandler( sender, e ) { document.location.href = e.MenuItemCommandArgument + "?id=" + e.LinkCommandArgument ; } // C# SERVER-SIDE HANDLER EXAMPLE private void Contextmenu2_ItemClick(object sender, MarkItUp.WebControls.ItemClickEventArgs e) { Response.Redirect(e.MenuItemCommandArgument + "?id=" + e.LinkCommandArgument ) ; }