The IWebPartField Interface versus the ASP.NET Lifecycle
A Webpart receives a filter value through the IWebPartField interface. The example over at MSDN was simple and clean. So I adopted the code to my Webpart.
A common scenario would be to create controls based on the received filter value. E.g. query a list for the passed filter value, and display the item from the query.
Problem
From the ASP.NET Lifecycle we know how to deal with controls. Create them in CreateChildControls, assign values in OnPreRender and let them being rendered in RenderContents. Now we have a problem. The passed value in our Webpart is not available at any place, where we can still add controls to the page. If we try to do in RenderContens, they are not shown. It’s too late.
The example stores the passed value in
private object _fieldValue;
On OnPreRender a method is called, which will process the filter data.
protected override void OnPreRender(EventArgs e) { if (_provider != null) { _provider.GetFieldValue(new FieldCallback(GetFieldValue)); } base.OnPreRender(e); }
The example will render the received value in RenderContents
protected override void RenderContents(HtmlTextWriter writer) { if (_provider != null) { PropertyDescriptor prop = _provider.Schema; if (prop != null && _fieldValue != null) { writer.Write(prop.DisplayName + ": " + _fieldValue); }...
Unfortunately this is too late for me. As stated above, you can’t add controls to the Controls collection of a page/Webpart anymore.
Solution
As soon as the value is being received from the Webpart connection, we use it to create controls or do stuff with it before the lifecycle reaches Render.
Instead of the private field _fieldValue, I used a property “FieldValue” with a backing field “_FieldValue”. The setter of the property assigns the new value to _FieldValue and triggers another method which will create controls. Assigning the value is just before Render.
private object _FieldValue public object FieldValue { get { return _FieldValue; } set { _FieldValue = value; DoStuff(); } }