Friday, March 6, 2009

Handling Postbacks using MenuItemTemplate

When using a MenuItemTemplate to perform a postback (instead of a navigate), handling the postback can be tricky. If you have several MenuItems, you will end up writing a lot of code to determine the menuitem that caused the postback and parsing the eventargument data.

Patrick Rodgers came up with a subclassed MenuItemTemplate in this post(http://www.thesug.org/blogs/patrickr/Lists/Posts/Post.aspx?ID=18) that targets itself for the postback and raises an event. You simply have to subscribe to the event and handle the postback there.

Here’s Patrick’s code:

using System;
using System.Web.UI;
using Microsoft.SharePoint.WebControls;

namespace Example
{
public class PostBackEventMenuItem : MenuItemTemplate, IPostBackEventHandler
{
public PostBackEventMenuItem()
: base() { }

public PostBackEventMenuItem(string text)
: base(text) { }

public PostBackEventMenuItem(string text, string imageUrl)
: base(text, imageUrl) { }

public PostBackEventMenuItem(string text, string imageUrl, string clientOnClickScript)
: base(text, imageUrl, clientOnClickScript) { }

protected override void EnsureChildControls()
{
if (!this.ChildControlsCreated)
{
base.EnsureChildControls();
if (string.IsNullOrEmpty(this.ClientOnClickUsingPostBackEvent))
{
this.ClientOnClickUsingPostBackEventFromControl(this);
}
}
}

#region IPostBackEventHandler Members

public void RaisePostBackEvent(string eventArgument)
{
EventHandler<EventArgs> handler = this.OnPostBackEvent;
if (handler != null)
{
handler(this, new EventArgs());
}
}

#endregion

public event EventHandler<EventArgs> OnPostBackEvent;
}
}

To use the control, register it in an aspx page, add the PostbackEventMenuItem and subscribe to the OnPostBackEvent.


<%@ Register TagPrefix="SharePoint" 
Namespace="Microsoft.SharePoint.WebControls"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Utilities"
Namespace="Microsoft.SharePoint.Utilities"
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="Example"
Namespace="Example" Assembly="Example, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=2bb7d29b4348a50b" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Control Language="C#" AutoEventWireup="true"
ClassName="Welcome" CompilationMode="Always" %>

<script runat="server">

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
this.ExplicitLogout.Visible = true;
}
else
{
this.ExplicitLogin.Visible = true;
this.ExplicitLogin.Attributes.CssStyle.Add("display", "block");
}
}

protected void HandlePostback(object sender, EventArgs e)
{
//remove all cookies, redirect to login with current page url
FormsAuthentication.SignOut();

Response.Redirect(string.Format("/_layouts/Authenticate.aspx?Source={0}", HttpUtility.UrlEncode(HttpContext.Current.Request.Url.AbsoluteUri)));
}

</script>

<SharePoint:PersonalActions AccessKey="<%$Resources:wss,personalactions_menu_ak%>"
ToolTip="<%$Resources:wss,open_menu%>" runat="server"
ID="ExplicitLogout" Visible="false">
<CustomTemplate>
<SharePoint:FeatureMenuTemplate
runat="server" FeatureScope="Site"
Location="Microsoft.SharePoint.StandardMenu"
GroupId="PersonalActions" ID="ID_PersonalActionMenu" UseShortId="true">
<SharePoint:MenuItemTemplate
runat="server" ID="ID_PersonalInformation"
Text="<%$Resources:wss,personalactions_personalinformation%>"
Description="<%$Resources:wss,personalactions_personalinformationdescription%>"
MenuGroupId="100" Sequence="100" ImageUrl="/_layouts/images/menuprofile.gif"
UseShortId="true" />
<example:postbackeventmenuitem
runat="server" id="Example_LoginAsDifferentUser"
text="<%$Resources:wss,personalactions_loginasdifferentuser%>"
description="<%$Resources:wss,personalactions_loginasdifferentuserdescription%>"
menugroupid="200" sequence="100" useshortid="true" ononpostbackevent="HandlePostback" />
<SharePoint:MenuItemTemplate
runat="server" ID="ID_RequestAccess"
Text="<%$Resources:wss,personalactions_requestaccess%>"
Description="<%$Resources:wss,personalactions_requestaccessdescription%>" MenuGroupId="200"
UseShortId="true" Sequence="200" />
<SharePoint:MenuItemTemplate
runat="server" ID="ID_Logout"
Text="<%$Resources:wss,personalactions_logout%>"
Description="<%$Resources:wss,personalactions_logoutdescription%>" MenuGroupId="200"
Sequence="300" UseShortId="true" Visible="true" />
<SharePoint:MenuItemTemplate
runat="server" ID="ID_PersonalizePage"
Text="<%$Resources:wss,personalactions_personalizepage%>"
Description="<%$Resources:wss,personalactions_personalizepagedescription%>" ImageUrl="/_layouts/images/menupersonalize.gif"
ClientOnClickScript="javascript:MSOLayout_ChangeLayoutMode(true);" PermissionsString="AddDelPrivateWebParts,UpdatePersonalWebParts"
PermissionMode="Any" MenuGroupId="300" Sequence="100" UseShortId="true" />
<SharePoint:MenuItemTemplate
runat="server" ID="ID_SwitchView" MenuGroupId="300"
Sequence="200" UseShortId="true" />
<SharePoint:MenuItemTemplate
runat="server" ID="MSOMenu_RestoreDefaults"
Text="<%$Resources:wss,personalactions_restorepagedefaults%>"
Description="<%$Resources:wss,personalactions_restorepagedefaultsdescription%>"
ClientOnClickNavigateUrl="javascript:MSOWebPartPage_RestorePageDefault()" MenuGroupId="300"
Sequence="300" UseShortId="true" />
</SharePoint:FeatureMenuTemplate>
</CustomTemplate>
</SharePoint:PersonalActions>
<SharePoint:ApplicationPageLink runat="server" ID="ExplicitLogin" ApplicationPageFileName="Authenticate.aspx"
AppendCurrentPageUrl="true" Text="<%$Resources:wss,login_pagetitle%>" Style="display: none"
Visible="false" />

No comments:

Post a Comment