views:

447

answers:

3

Say you have several webparts, one as a controller and several which take information from the controller and act on it. This is fairly easy to model using the Consumer/Producer interface introduced in ASP 2.0.

How would you be able to add interactions the other way around whilst still maintaining the above?

A simple example would be: the user enters information into webpart A which performs a search and the results would be displayed on webpart B. Webpart C allows you to filter the results which should trigger webpart A to re-submit the query and hence update the results in B.

It doesn't seem possible to do in WSS 3.0 because you are only allowed 1 interface to be used in all of the connections at any one time.

Does this even make sense ? :-)

+2  A: 

A quick and dirty solution to enable arbitrary control communication is to use recursive find control and events. Have the controls search the control tree by control type for what they need and then subscribe to publicly exposed events on the publishing control.

I have previous used the trick to enable standard server controls to find each other when embedded in CMS systems from different vendors to avoid a specific communication API entirely.

that's a bit nasty :D
Gordon Carpenter-Thompson
+1  A: 

I don't see anything wrong with webpart A getting a reference to webpart B and calling public/internal methods/properties or subscribing handlers to public/internal events. One point of mention when doing this though: EnsureChildControls. I have witnessed with my own eyes one webpart being run clear to PreRender while another webpart hadn't even run CreateChildControls.

From webpart A, fetch your reference to webpart B (in this case webpart B is of type Calendar) like so:

     private Calendar _calendarWP = null;
    public Calendar CalendarWP
    {
      get
      {
          if (_calendarWP != null)
              return _calendarWP;
          else
              foreach (System.Web.UI.WebControls.WebParts.WebPartZone zone in this.WebPartManager.Zones)
                  foreach (System.Web.UI.WebControls.WebParts.WebPart webpart in zone.WebParts)
                      if (webpart is Calendar)
                      {
                          _calendarWP = (Calendar)webpart;
                          _calendarWP.EnsureChildControls();
                          return _calendarWP;
                      }
          return null;
      }
    }

Now you can do things like fetch some new data and update the Calendar like so:

         IEnumerable newData = SomeDataProvider.GetNewData(args);
        CalendarWP.someGridView.DataSource = newData;
        CalendarWP.someGridView.DataBind();

Or perhaps let webpart A toss a reference to itself over to webpart B so it can use webpart A's public/internal properties to go fetch data for itself:

CalendarWP.UseWPAToFetchData(this);
andrew
A: 

very useful