N
news.microsoft.com
I am having some trouble with my webpart connections on postbacks.
I basically have two webparts in the same zone, 1 provider and 1 consumer.
The provider has a dropdown list and submit button and the consumer has a
text box that displays data depending on what is selected in the provider.
On the initial page hit, The consumer connection is established before the
CreateChildControls event (which is fine), but on the postback, the
CreateChildControls event occurs before the consumer connection is
established, so the the CreateChildControls method does not know which value
was selected in the provider at this time.
Does anyone else have this problem or know the correct way to do this?
I've noticed that the CreateChildControls only gets fired before the
connection gets established when there are any input (text, checkbox, etc)
controls on the form. If you run the code below, you'll notice the consumer
is only rendered every other postback because when the connection isn't set,
the consumer can't render the control because it doesn't know which type to
display. And when the consumer has no input controls, on the next postback,
the connection is established first and the controls get rendered.
I've come up with a workaround, but I'd like a cleaner solution. My
workaround is to just call CreateChildControls again in the Consumer
connection code (You'll see it commented out in the code below). This will
ensure that the controls are created again after the connection has been
made. I don't like this because 1) On the initial page hit the controls we
be rendered and then deleted and re-rendered when the connection is made
which is inefficient.
I guess some other questions would be...
1. I know the CreateChildControls event is called at different times
depending on page circumstances, but does anyone know those circumstances?
2. Is there a way to make sure that the connection happens before the
CreateChildControls? Or a way to force the connection at some point in the
page life cycle?
Any help with this would be greatly appreciated... I've been banging my head
against this one for a couple days now.
Thanks!!!
Code follows...
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" EnableViewState="false"%>
<%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.CS.Controls" %>
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="mgr" runat="server">
<StaticConnections>
<asp:WebPartConnection ID="conn1"
ConsumerConnectionPointID="MyConsumer"
ConsumerID="consumer1"
ProviderConnectionPointID="MyProvider"
ProviderID="provider1" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<aspSample:ZipCodeWebPart ID="provider1" runat="server" Title="My
Provider" />
<aspSample:WeatherWebPart ID="consumer1" runat="server" Title="My
Consumer" />
</ZoneTemplate>
</asp:WebPartZone>
<asp:ConnectionsZone ID="ConnectionsZone1" runat="server">
</asp:ConnectionsZone>
</form>
</body>
</html>
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;
public interface IMyConnection
{
string MySelection { get; }
}
public class ZipCodeWebPart : WebPart, IMyConnection
{
private string _mySelection = String.Empty;
private DropDownList _dll;
public ZipCodeWebPart()
{
}
public virtual string MySelection
{
get { return _mySelection; }
}
[ConnectionProvider("Zip Code Provider", "MyProvider")]
public IMyConnection ProvideMyProvider()
{
return this;
}
protected override void CreateChildControls()
{
Controls.Clear();
_dll = new DropDownList();
_dll.Items.Add("One");
_dll.Items.Add("Two");
_dll.Items.Add("Three");
_dll.CausesValidation = true;
this.Controls.Add(_dll);
Button myButton = new Button();
myButton.Text = "Display";
myButton.Click +=new EventHandler(myButton_Click);
this.Controls.Add(myButton);
}
void myButton_Click(object sender, EventArgs e)
{
_mySelection = _dll.SelectedValue;
}
}
public class WeatherWebPart : WebPart
{
private IMyConnection _provider;
[ConnectionConsumer("Zip Code Consumer", "MyConsumer")]
public void GetMyProvider(IMyConnection Provider)
{
_provider = Provider;
}
protected override void OnPreRender(EventArgs e)
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
if (this._provider != null)
{
Controls.Clear();
TextBox tb = new TextBox();
tb.ID = "myTextBox";
this.Controls.Add(tb);
switch (_provider.MySelection)
{
case "One":
tb.Text = "Display One Data";
break;
case "Two":
tb.Text = "Display Two Data";
break;
case "Three":
tb.Text = "Display Three Data";
break;
}
}
}
}
}
I basically have two webparts in the same zone, 1 provider and 1 consumer.
The provider has a dropdown list and submit button and the consumer has a
text box that displays data depending on what is selected in the provider.
On the initial page hit, The consumer connection is established before the
CreateChildControls event (which is fine), but on the postback, the
CreateChildControls event occurs before the consumer connection is
established, so the the CreateChildControls method does not know which value
was selected in the provider at this time.
Does anyone else have this problem or know the correct way to do this?
I've noticed that the CreateChildControls only gets fired before the
connection gets established when there are any input (text, checkbox, etc)
controls on the form. If you run the code below, you'll notice the consumer
is only rendered every other postback because when the connection isn't set,
the consumer can't render the control because it doesn't know which type to
display. And when the consumer has no input controls, on the next postback,
the connection is established first and the controls get rendered.
I've come up with a workaround, but I'd like a cleaner solution. My
workaround is to just call CreateChildControls again in the Consumer
connection code (You'll see it commented out in the code below). This will
ensure that the controls are created again after the connection has been
made. I don't like this because 1) On the initial page hit the controls we
be rendered and then deleted and re-rendered when the connection is made
which is inefficient.
I guess some other questions would be...
1. I know the CreateChildControls event is called at different times
depending on page circumstances, but does anyone know those circumstances?
2. Is there a way to make sure that the connection happens before the
CreateChildControls? Or a way to force the connection at some point in the
page life cycle?
Any help with this would be greatly appreciated... I've been banging my head
against this one for a couple days now.
Thanks!!!
Code follows...
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" EnableViewState="false"%>
<%@ Register TagPrefix="aspSample" Namespace="Samples.AspNet.CS.Controls" %>
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:WebPartManager ID="mgr" runat="server">
<StaticConnections>
<asp:WebPartConnection ID="conn1"
ConsumerConnectionPointID="MyConsumer"
ConsumerID="consumer1"
ProviderConnectionPointID="MyProvider"
ProviderID="provider1" />
</StaticConnections>
</asp:WebPartManager>
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<aspSample:ZipCodeWebPart ID="provider1" runat="server" Title="My
Provider" />
<aspSample:WeatherWebPart ID="consumer1" runat="server" Title="My
Consumer" />
</ZoneTemplate>
</asp:WebPartZone>
<asp:ConnectionsZone ID="ConnectionsZone1" runat="server">
</asp:ConnectionsZone>
</form>
</body>
</html>
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;
public interface IMyConnection
{
string MySelection { get; }
}
public class ZipCodeWebPart : WebPart, IMyConnection
{
private string _mySelection = String.Empty;
private DropDownList _dll;
public ZipCodeWebPart()
{
}
public virtual string MySelection
{
get { return _mySelection; }
}
[ConnectionProvider("Zip Code Provider", "MyProvider")]
public IMyConnection ProvideMyProvider()
{
return this;
}
protected override void CreateChildControls()
{
Controls.Clear();
_dll = new DropDownList();
_dll.Items.Add("One");
_dll.Items.Add("Two");
_dll.Items.Add("Three");
_dll.CausesValidation = true;
this.Controls.Add(_dll);
Button myButton = new Button();
myButton.Text = "Display";
myButton.Click +=new EventHandler(myButton_Click);
this.Controls.Add(myButton);
}
void myButton_Click(object sender, EventArgs e)
{
_mySelection = _dll.SelectedValue;
}
}
public class WeatherWebPart : WebPart
{
private IMyConnection _provider;
[ConnectionConsumer("Zip Code Consumer", "MyConsumer")]
public void GetMyProvider(IMyConnection Provider)
{
_provider = Provider;
}
protected override void OnPreRender(EventArgs e)
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
if (this._provider != null)
{
Controls.Clear();
TextBox tb = new TextBox();
tb.ID = "myTextBox";
this.Controls.Add(tb);
switch (_provider.MySelection)
{
case "One":
tb.Text = "Display One Data";
break;
case "Two":
tb.Text = "Display Two Data";
break;
case "Three":
tb.Text = "Display Three Data";
break;
}
}
}
}
}