Adding WebParts via code behind?

  • Thread starter Bart Van Hemelen
  • Start date
B

Bart Van Hemelen

I'm working on a project where the user of a site will receive custom
content, depending on a set of parameters. The content will all be
contained in UserControls (.ascx), that will be used as webparts on a
page.

We need to add the webparts dynamically to the site, depending on the
status of the user: this involves a personalisation of a travel
website, so a user can be "before" a trip, "during" a trip and "after"
a trip, and depending on that status he'll see different content. (This
is just one of the parameters, actually.) Of course, this all needs to
integrate with the built-in personalisation offered by Profiles.

However, all my experiments with adding UCs/WebParts via code behind
have failed miserably: adding the works, but whenever the user clicks
on a button inside a webpart, the postback causes the webparts to
multiply.

I've looked around, but so far I haven't yet found a working example of
what I want to do. Can anyone help me out? Or am I trying to do
something that is impossible?

Tools & technologies: ASP.NET 2.0 / C# / Visual Studio 2005
 
C

Cowboy \(Gregory A. Beamer\)

The WebPart Framework is designed to declaratively do the work for you,
storing user choices in profile. When you dynamically add bits, you can end
up with dupes in one of two ways.

1. The user has an item in his profile and you have also added that item
or
2. The web part/control is held in ViewState and you dynamically add one,
thinking this is the only way to change a control's state.

In either case, you now have two objects (one created originally either by
the user's choice or your initial load on the page (and into ViewState) plus
the one you added when the form posted back).

User Controls can act a lot like web parts, although they have fewer moving
parts.

Another thing: Page_Load is for loading a page. While this sounds like
"well, duh" I find so few people really get the lifecycle. If you are
loading a page and then allowing the controls to reside in ViewState, you
need to make sure the initial load is ONLY in Not is Postback. In most
cases, the pattern for page load is this (pseudocode):

Page_Load

If this is not a postback
'Load elements necessary for page view
Else
'Only load things necessary for EVERY
' postback here (i.e. 100% of the time)
End

END

You handle all other manipulation in the events. If you have a Page_Load
that has a huge amount of code, you are probably working out a huge
anti-pattern. That is not wise.
What I would suggest is taking a step back and running through a full debug
cycle on a page that is "failing" (by your spec -- i.e. adding additional
web parts, etc.). Set watches on the number of controls, breakpoints in
different methods, etc. and watch what is happening. Turn on and off
ViewState. This exercise will not directly solve your issue, but it will
truly enlighten you as to what Microsoft is doing for you.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

*************************************************
Think outside the box!
*************************************************
 
B

Bart Van Hemelen

Cowboy said:
The WebPart Framework is designed to declaratively do the work for you,
storing user choices in profile. When you dynamically add bits, you can end
up with dupes in one of two ways.

1. The user has an item in his profile and you have also added that item
or
2. The web part/control is held in ViewState and you dynamically add one,
thinking this is the only way to change a control's state.

I now do this in Page_Load:

if ( WebPartZone1.WebParts.Count)
{
// add UCs as WebParts here
}

which seems to have solved the problem: no duplicate webparts,
postbacks work as they should etc. The state of those webparts -- i.e.
if they are minimized or not -- also seems to get saved in the Profile.

(Of course, it also means that I cannot put any WebParts on the page
unless I do it via this method, but that's a price I'm willing to pay.)
You handle all other manipulation in the events. If you have a Page_Load
that has a huge amount of code, you are probably working out a huge
anti-pattern. That is not wise.

I realise that, but other factors are more important to my employers:
timely delivery, for at least a cost as possible. I'm particularly
interested in knowing how I "should" solve this problem, i.e. how
Microsoft wants me to solve this problem, since I do want to do this
the proper way.

However, after having gone through numerous examples I still haven't
encountered any that resemble what I need to do, which is serve users
with a custom list of webparts that depends on a number of factors
which will be derived from an existing framework.
 
B

Bart Van Hemelen

Bart said:
I now do this in Page_Load:

if ( WebPartZone1.WebParts.Count)
{
// add UCs as WebParts here
}

which seems to have solved the problem: no duplicate webparts,
postbacks work as they should etc. The state of those webparts -- i.e.
if they are minimized or not -- also seems to get saved in the Profile.

It seems I spoke too soon. I just wrote some quick code to check if
this would work, and after cleaning it up -- i.e. inserting the proper
titles for each fo the uc-webparts for instance -- and retesting it, of
course I got the webparts I expected, plus all the old ones that were
saved in the profile.

Considering that the website is going to be very dynamic in the future,
we must have 100% control of the uc-webparts the user will have access
to.

So I need to either a) find the proper way of adding uc-webparts
dynamically, or b) figure out a way to remove the improper ones from
the profile.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top