Attention: We are retiring the ASP.NET Community Blogs. Learn more >

ContextMenu - working in the designer

I've now got the ContextMenu to emit all of the Javascript into the page as part of it's rendering process which is the first part of what I said needed to be done from yesterday. Here is the code in the ContextMenu class which is responsible for doing that:

'/ <summary>
'/ Overrides <see cref="Control.OnPreRender"/>
'/ </summary>
Protected Overrides Sub OnPreRender(ByVal e As EventArgs)
    MyBase.OnPreRender(e)
    RegisterClientScript()
End Sub

'/ <summary>
'/ Registers the neccessary clientscript for the context menu.
'/ </summary>
Protected Overridable Sub RegisterClientScript()
    ' First time only...
    If Not Me.Page.IsClientScriptBlockRegistered(mScriptKey) Then
        ' Insert the global array declaration...
        Dim strng As String = _
            String.Format( _
                "<script language='javascript' type='text/javascript' >{0}var MarkItUp_ContextMenu = new Array() ;{0}", _
                Environment.NewLine _
            )
        ' Insert the global scripts...
        Dim reader As New System.IO.StreamReader(GetType(ContextMenu).Assembly.GetManifestResourceStream(GetType(ContextMenu), "ContextMenuScript.js"))
        strng &= String.Format( _
            "{0}<!--{0}{1}{0}//-->{0}</script>", _
            Environment.NewLine, reader.ReadToEnd() _
        )
        Me.Page.RegisterClientScriptBlock(mScriptKey, strng)
    End If
    ' Every time this control appears on a page, add an entry into the global
    ' array declaration for this menu and its items...
    Dim meCtl As String = String.Format("<script language='javascript' type='text/javascript' >{1}MarkItUp_ContextMenu[""{0}""] = [{1}", Me.ClientID, Environment.NewLine)
    For Each item As ContextMenuItem In Me.Items
        meCtl &= "    [ ['" & item.Text & "'], '" & item.CommandArgument & "' , '" & item.ClientNotificationFunction & "' ]," & Environment.NewLine
    Next
    If meCtl.EndsWith(","c) Then
        meCtl = meCtl.Substring(0, meCtl.Length - 1)
    End If
    meCtl &= String.Format("] ;{0}</script>", Environment.NewLine)
    Me.Page.RegisterClientScriptBlock(mScriptKey & "_" & Me.ClientID, meCtl)
End Sub

 

The other cool thing that I've done is to implement Andy Smith's type converter class (well, had to modify it slightly for VB obviously) so that whenever a ContextMenuLink is dropped onto the designer, a dropdown list of all possible ContextMenu's on the page is displayed in the property grid

Excellent designer support.

The only task that is remaining is to implement the IPostBackEventHandler interface so that clicking a context menu item will generate a server postback if the ClientNotificationFunction property of the ContextMenuItem is empty and also to do some fine-tuning of the dhtml positioning in the global client scripts for ContextMenu.

No Comments