ProxyWebPartManager Class

Provides a way for developers to declare static connections in a content page when a WebPartManager control has been declared in the content page's associated master page.

Namespace:  System.Web.UI.WebControls.WebParts
Assembly:  System.Web (in System.Web.dll)

[BindableAttribute(false)]
[AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public class ProxyWebPartManager : Control
<asp:ProxyWebPartManager />

The ProxyWebPartManager control exists for the particular scenario of declaring static connections in content pages when a WebPartManager control has already been declared in a master page.

By design, a Web page that uses Web Parts controls must contain one (and only one) WebPartManager control that manages all Web Parts controls on the page. When a Web Parts application uses master pages, it is common to place the WebPartManager control in the master page, because all the content pages are merged with the master page at run time and the single WebPartManager control will manage all the Web Parts controls from all content pages. However, when developers want to declare static connections in the content pages of such an application, they might seem to face a limitation. A static Web Parts connection can be declared only by adding an <asp:webpartconnection> element as a child of a <staticconnections> element, which itself must be a child of a <asp:webpartmanager> element. But because the WebPartManager control was already declared in the master page, and is the one permitted WebPartManager control, developers cannot declare additional WebPartManager controls in the content pages to add static connections.

The ProxyWebPartManager control takes the place of the WebPartManager control in this scenario. Developers declare an <asp:proxywebpartmanager> element instead of an <asp:webpartmanager> element in their content pages, and can then declare static connections as child elements. At run time, the connections in the ProxyWebPartManager control are simply added to the StaticConnections collection of the WebPartManager control and treated like any other connection.

Because the ProxyWebPartManager control is used only in this particular development scenario, it has more limited functionality than the WebPartManager class. In fact, although the ProxyWebPartManager control acts as a proxy to contain static connections for the WebPartManager control in content pages, it does not inherit from the WebPartManager control. It inherits directly from the Control class, and overrides only a few of the base members. The EnableTheming, Visible, and SkinID properties are overridden and assigned values that prevent them from being used. Other inherited properties are overridden to adjust their design-time behavior, but otherwise they have the same behavior as the base properties. These include the Controls and ClientID properties. Finally, the ProxyWebPartManager class has one non-inherited property. The StaticConnections property returns its own collection of static connections (a ProxyWebPartConnectionCollection object).

As for methods, the ProxyWebPartManager class similarly overrides only a few methods, mostly to restrict their use. The inherited Focus method is made unusable by throwing an exception if called. The CreateControlCollection method always returns an empty control collection, which has the effect of preventing it from being able to contain a collection of controls. Finally, the OnInit method calls the base method, and then assigns the collection of connections referenced by the StaticConnections property to the WebPartManager.StaticConnections property of the WebPartManager control. This has the effect of rolling up all the static connections declared in all content pages and making them part of the connections collection maintained by the WebPartManager control in the master page.

The following code example demonstrates how to use the ProxyWebPartManager class to declare static connections on content pages in an application that uses master pages. The example has five parts:

  • A user control that enables you to change the Web Parts display mode on a page.

  • Source code for an interface and two WebPart controls acting as the provider and the consumer for a connection.

  • A master Web page that hosts the user control, the content pages, and the WebPartManager control for the application.

  • A content Web page that hosts a ProxyWebPartManager control, the two custom WebPart controls, and a static connection to connect the two controls.

  • An explanation of how to run the example page.

The first part of this code example is the user control that enables users to change display modes on a Web page. Save the following source code to an .ascx file, giving it the file name that is assigned to the Src attribute of the Register directive for this user control, which is near the top of the hosting master page. For details about display modes and a description of the source code in this control, see Walkthrough: Changing Display Modes on a Web Parts Page.

<%@ control language="C#" classname="DisplayModeMenuCS"%>
<script runat="server">

 // Use a field to reference the current WebPartManager.
  WebPartManager _manager;

  void Page_Init(object sender, EventArgs e)
  {
    Page.InitComplete += new EventHandler(InitComplete);
  }  

  void InitComplete(object sender, System.EventArgs e)
  {
    _manager = WebPartManager.GetCurrentWebPartManager(Page);

    String browseModeName = WebPartManager.BrowseDisplayMode.Name;

    // Fill the dropdown with the names of supported display modes. 
    foreach (WebPartDisplayMode mode in _manager.SupportedDisplayModes)
    {
      String modeName = mode.Name;
      // Make sure a mode is enabled before adding it. 
      if (mode.IsEnabled(_manager))
      {
        ListItem item = new ListItem(modeName, modeName);
        DisplayModeDropdown.Items.Add(item);
      }
    }

    // If shared scope is allowed for this user, display the scope-switching 
    // UI and select the appropriate radio button for the current user scope. 
    if (_manager.Personalization.CanEnterSharedScope)
    {
      Panel2.Visible = true;
      if (_manager.Personalization.Scope == PersonalizationScope.User)
        RadioButton1.Checked = true;
      else
        RadioButton2.Checked = true;
    }

  }

  // Change the page to the selected display mode. 
  void DisplayModeDropdown_SelectedIndexChanged(object sender, EventArgs e)
  {
    String selectedMode = DisplayModeDropdown.SelectedValue;

    WebPartDisplayMode mode = _manager.SupportedDisplayModes[selectedMode];
    if (mode != null)
      _manager.DisplayMode = mode;
  }

  // Set the selected item equal to the current display mode. 
  void Page_PreRender(object sender, EventArgs e)
  {
    ListItemCollection items = DisplayModeDropdown.Items;
    int selectedIndex = 
      items.IndexOf(items.FindByText(_manager.DisplayMode.Name));
    DisplayModeDropdown.SelectedIndex = selectedIndex;
  }

  // Reset all of a user's personalization data for the page. 
  protected void LinkButton1_Click(object sender, EventArgs e)
  {
    _manager.Personalization.ResetPersonalizationState();
  }

  // If not in User personalization scope, toggle into it. 
  protected void RadioButton1_CheckedChanged(object sender, EventArgs e)
  {
    if (_manager.Personalization.Scope == PersonalizationScope.Shared)
      _manager.Personalization.ToggleScope();
  }

  // If not in Shared scope, and if user is allowed, toggle the scope. 
  protected void RadioButton2_CheckedChanged(object sender, EventArgs e)
  {
    if (_manager.Personalization.CanEnterSharedScope && 
        _manager.Personalization.Scope == PersonalizationScope.User)
      _manager.Personalization.ToggleScope();
  }
</script>
<div>
  <asp:Panel ID="Panel1" runat="server" 
    Borderwidth="1" 
    Width="230" 
    BackColor="lightgray"
    Font-Names="Verdana, Arial, Sans Serif" >
    <asp:Label ID="Label1" runat="server" 
      Text="&nbsp;Display Mode" 
      Font-Bold="true"
      Font-Size="8"
      Width="120" 
      AssociatedControlID="DisplayModeDropdown"/>
    <asp:DropDownList ID="DisplayModeDropdown" runat="server"  
      AutoPostBack="true" 
      Width="120"
      OnSelectedIndexChanged="DisplayModeDropdown_SelectedIndexChanged" />
    <asp:LinkButton ID="LinkButton1" runat="server"
      Text="Reset User State" 
      ToolTip="Reset the current user's personalization data for the page."
      Font-Size="8" 
      OnClick="LinkButton1_Click" />
    <asp:Panel ID="Panel2" runat="server" 
      GroupingText="Personalization Scope"
      Font-Bold="true"
      Font-Size="8" 
      Visible="false" >
      <asp:RadioButton ID="RadioButton1" runat="server" 
        Text="User" 
        AutoPostBack="true"
        GroupName="Scope" OnCheckedChanged="RadioButton1_CheckedChanged" />
      <asp:RadioButton ID="RadioButton2" runat="server" 
        Text="Shared" 
        AutoPostBack="true"
        GroupName="Scope" 
        OnCheckedChanged="RadioButton2_CheckedChanged" />
    </asp:Panel>
  </asp:Panel>
</div>

The second part of the code example is the source code for the interface and controls. The source file contains a simple interface named IZipCode. There is also a WebPart class named ZipCodeWebPart that implements the interface and acts as the provider control. Its ProvideIZipCode method is the callback method that implements the interface's only member. The method simply returns an instance of the interface. Note that the method is marked with a ConnectionProvider attribute in its metadata. This is the mechanism for identifying the method as the callback method for the provider's connection point. The other WebPart class is named WeatherWebPart, and it acts as the consumer for the connection. This class has a method named GetZipCode that gets an instance of the IZipCode interface from the provider control. Note that this method is marked as the consumer's connection point method with a ConnectionConsumer attribute in its metadata.

For the code example to run, you must compile this source code. You can compile it explicitly and put the resulting assembly in your Web site's Bin folder or the global assembly cache. Alternatively, you can put the source code in your site's App_Code folder, where it will be dynamically compiled at run time. This code example uses dynamic compilation. For a walkthrough that demonstrates how to compile, see Walkthrough: Developing and Using a Custom Web Server Control.

namespace Samples.AspNet.CS.Controls
{
  using System;
  using System.Web;
  using System.Web.Security;
  using System.Security.Permissions;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;

  [AspNetHostingPermission(SecurityAction.Demand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  [AspNetHostingPermission(SecurityAction.InheritanceDemand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  public interface IZipCode
  {
    string ZipCode { get; set;}
  }


  [AspNetHostingPermission(SecurityAction.Demand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  [AspNetHostingPermission(SecurityAction.InheritanceDemand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  public class ZipCodeWebPart : WebPart, IZipCode
  {
    string zipCodeText = String.Empty;
    TextBox input;
    Button send;

    public ZipCodeWebPart()
    {
    }

    // Make the implemented property personalizable to save  
    // the Zip Code between browser sessions.
    [Personalizable()]
    public virtual string ZipCode
    {
      get { return zipCodeText; }
      set { zipCodeText = value; }
    }

    // This is the callback method that returns the provider.
    [ConnectionProvider("Zip Code Provider", "ZipCodeProvider")]
    public IZipCode ProvideIZipCode()
    {
      return this;
    }

    protected override void CreateChildControls()
    {
      Controls.Clear();
      input = new TextBox();
      this.Controls.Add(input);
      send = new Button();
      send.Text = "Enter 5-digit Zip Code";
      send.Click += new EventHandler(this.submit_Click);
      this.Controls.Add(send);
    }

    private void submit_Click(object sender, EventArgs e)
    {
      if (input.Text != String.Empty)
      {
        zipCodeText = Page.Server.HtmlEncode(input.Text);
        input.Text = String.Empty;
      }
    }

  }


  [AspNetHostingPermission(SecurityAction.Demand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  [AspNetHostingPermission(SecurityAction.InheritanceDemand,
    Level = AspNetHostingPermissionLevel.Minimal)]
  public class WeatherWebPart : WebPart
  {
    private IZipCode _provider;
    string _zipSearch;
    Label DisplayContent;

    // This method is identified by the ConnectionConsumer  
    // attribute, and is the mechanism for connecting with  
    // the provider. 
    [ConnectionConsumer("Zip Code Consumer", "ZipCodeConsumer")]
    public void GetIZipCode(IZipCode Provider)
    {
      _provider = Provider;
    }

    protected override void OnPreRender(EventArgs e)
    {
      EnsureChildControls();

      if (this._provider != null)
      {
        _zipSearch = _provider.ZipCode.Trim();
        DisplayContent.Text = "My Zip Code is:  " + _zipSearch;
      }
    }

    protected override void CreateChildControls()
    {
      Controls.Clear();
      DisplayContent = new Label();
      this.Controls.Add(DisplayContent);
    }

  }

}

The third part of the code example is the master page. You should take the following source code and save it in a file, naming it MasterPageCS.master or MasterPageVB.master (depending on which language you use). Note that the master page contains a Register directive to register the user control, and it references the user control itself in the body of the page. The master page also declares the single <asp:webpartmanager> element used for this page and all related content pages. Finally, the master page has an <asp: contentplaceholder> element that declares the point in the page where the content page is inserted.

<%@ Master Language="C#" %>
<%@ register tagprefix="uc1" 
    tagname="DisplayModeMenuCS"
    src="~/displaymodemenucs.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Master page with connections in content pages</title>
</head>
<body>
    <h2>Contoso, Ltd.</h2>
    <hr />
    <form id="form1" runat="server">
    <asp:webpartmanager runat="server" id="WebPartManager1" />
    <uc1:displaymodemenucs id="menu1" runat="server" />
    <div>
        <asp:contentplaceholder id="ContentPlaceHolder1" 
          runat="server" />
    </div>
    </form>
</body>
</html>

The fourth part of the code example is the content page. You should copy the following source code and save it in a file with an .aspx extension. Notice that its Page directive contains a MasterFile attribute to refer to the master page. Also, this page has a Register directive to register the file in the App_Code folder that contains the dynamically compiled custom WebPart controls that participate in the connection. Within the <asp:content> tags of the page, there is an <asp:proxywebpartmanager> element, with a child <staticconnections> element, which in turn has a child <asp:webpartconnection> element to declare the details of the connection. Within the <script> tags on the page, the Button1_Click method adds some code that accesses the main WebPartManager control in the master page and the ProxyWebPartManager control in the content page, and writes some of their details to the page.

<%@ Page Language="C#" MasterPageFile="~/MasterPageCS.master" 
  Title="Connections Page" %>
<%@ Register TagPrefix="aspSample" 
    Namespace="Samples.AspNet.CS.Controls" %>

<script runat="server">

  protected void Button1_Click(object sender, EventArgs e)
  {
    StringBuilder lblText = new StringBuilder();

    if (Page.Master.FindControl("WebPartManager1") != null)
    {
      WebPartManager theMgr = 
        (WebPartManager)Page.Master.FindControl("WebPartManager1");
      lblText.Append("WebPartManager:  <br /><pre>" +
        "  Master page file is " + Page.MasterPageFile + "<br />" +
        "  ID is " + theMgr.ID + "<br />" +
        "  Connection count is " +
           theMgr.StaticConnections.Count.ToString() + "<br />" +
        "  WebParts count is " +
           theMgr.WebParts.Count.ToString() + "</pre><br />");
    }

    if (proxymgr1 != null)
    {
      lblText.Append("ProxyWebPartManager:  <br /><pre>" +
        "  Content page file is " + Request.Path + "<br />" +
        "  ID is " + proxymgr1.ID + "<br />" +
        "  Connection count is " +
           proxymgr1.StaticConnections.Count.ToString() + 
           "</pre><br />");
    }

    Literal1.Text = lblText.ToString();

  }

</script>

<asp:Content ID="Content1" Runat="Server" 
  ContentPlaceHolderID="ContentPlaceHolder1" >

  <asp:proxywebpartmanager id="proxymgr1" runat="server">
    <staticconnections>
      <asp:webpartconnection id="connection1" 
        consumerconnectionpointid="ZipCodeConsumer"
        consumerid="zipConsumer"
        providerconnectionpointid="ZipCodeProvider" 
        providerid="zipProvider" />
    </staticconnections>    
  </asp:proxywebpartmanager>

  <div>
  <asp:webpartzone id="zone1" runat="server">
    <zonetemplate>
      <aspsample:zipcodewebpart id="zipProvider" runat="server" 
        title="Zip Code Provider"  />
      <aspsample:weatherwebpart id="zipConsumer" runat="server" 
        title="Zip Code Consumer" />
    </zonetemplate>
  </asp:webpartzone>
  </div>

  <div>
  <asp:button id="Button1" runat="server" 
    text="WebPartManager Information" onclick="Button1_Click" />
  <br />

  </div>

  <asp:connectionszone id="ConnectionsZone1" runat="server" />
  <asp:literal id="Literal1" runat="server" />

</asp:Content>

After you load the page in a browser, click the WebPartManager Information button and observe the information about the WebPartManager control in the master page, and the ProxyWebPartManager control in the content page. For example, note that they both have the same count in their respective properties that track static connections (the StaticConnections property). Note also that although the WebPartManager control has a WebParts property that tracks the number of WebPart controls it manages, the ProxyWebPartManager control has no such property, as its only purpose is to contain static connections.

System.Object
  System.Web.UI.Control
    System.Web.UI.WebControls.WebParts.ProxyWebPartManager

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 7, Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2008 R2, Windows Server 2008, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98

The .NET Framework and .NET Compact Framework do not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.

.NET Framework

Supported in: 3.5, 3.0, 2.0
Was this page helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft