Thursday, March 24, 2011

How to build a consumer web part in SharePoint 2010 using IWebPartParameters that works with HTML Form Web Part and Filter Web Parts?

Scenario:
How to build a consumer web part in SharePoint 2010 using IWebPartParameters that works with HTML Form Web Part and Filter Web Parts?

Explanation:
The current SharePoint 2010 documentation still includes reference to an API interface which it says is obsolete.

[ObsoleteAttribute("Use System.Web.UI.WebControls.WebParts.IWebPartParameters instead")]
public interface IFilterConsumer

As we can see, the interface displays a message that says "Use System.Web.UI.WebControls.WebParts.IWebPartParameters instead."
Unfortunately, it's hard to find any good examples out there for writing a Web Part that uses the IWebPartParamters interface for consuming the HTML Form Web Part / Filter Web Parts.

There is one brilliant example here but I had to tweak it slightly to get it working.

Solution:
For the purpose of this demo, I need to capture value for "Zip Code" from the provider web part which is an HTML Form Web Part.

We will need to create a public property in the web part called "ProviderZipCode".

Code:

[ToolboxItemAttribute(false)]
    public class DemoWebPart : System.Web.UI.WebControls.WebParts.WebPart, IWebEditable, IWebPartParameters
    {

        #region Private Members

        private List<IFilterValues> _filterProviders;

        IWebPartParameters _provider = null;
        IDictionary _data = null;
        
        #endregion

        #region Public Properties
        
        /// <summary>
        /// Zip Code from provider web part
        /// </summary>
        public string ProviderZipCode
        {
            get;
            set;
        }
        
        #endregion

        #region Constructor
        
        public DemoWebPart()
        {
            _filterProviders = new List<IFilterValues>();
        }
        
        #endregion

        #region Control Events
        
        protected override void OnPreRender(EventArgs e)
        {
            if (this._provider != null)
            {
                this._provider.GetParametersData(new ParametersCallback(SetProviderData));
            }

            //Get the value (zip code) from the provider web part
            String zipCodeFromProvider = GetFilterValue();

            base.OnPreRender(e);
        }
        
        #endregion

        #region IWebEditable Members
        
        EditorPartCollection IWebEditable.CreateEditorParts()
        {
            //Return the editor part used with this web part.  This builds a
            //custom editor with dropdowns and an asset url selector.

            List<EditorPart> editors = new List<EditorPart>();
            editors.Add(new DemoEditorPart());
            return new EditorPartCollection(editors);
        }
        
        #endregion

        #region Webpart Connections - Consumer

        [ConnectionConsumer("Parameters Data")]
        public void SetProvider(IWebPartParameters provider)
        {
            if (provider != null)
            {
                PropertyDescriptorCollection props = TypeDescriptor.GetProperties(this);
                PropertyDescriptor p1 = props.Find("ProviderZipCode", false);

                PropertyDescriptorCollection schemaProps = new PropertyDescriptorCollection(new PropertyDescriptor[] { p1 });

                provider.SetConsumerSchema(schemaProps);
                this._provider = provider;
            }
        }

        public void SetProviderData(IDictionary dict)
        {
            this._data = dict;
        }

        private string GetFilterValue()
        {
            if (this._provider != null && this._data != null)
            {
                if (_data["ProviderZipCode"] != null)
                {
                    ProviderZipCode = _data["ProviderZipCode"].ToString();
                    return ProviderZipCode;
                }
            }
            return "";
        }

        public void SetConsumerSchema(PropertyDescriptorCollection schema)
        {
            throw new Exception("Not implemented.");
        }

        public void GetParametersData(ParametersCallback callback)
        {
            throw new Exception("Not implemented.");
        }

        public PropertyDescriptorCollection Schema
        {
            get { throw new Exception("Not implemented."); }
        }

        #endregion
    }

After the web part is deployed, I have added an HTML Form Web Part.


When we attempt to connect the HTML Web Part (Provider) to the web part we just deployed (I gave it's title "Find Nearest Locations From A ZipCode" ), we can see our web part in the list of connectible web parts.

In the next screen, we see the provider and consumer field names.
As we can notice in the below picture, our custom property "ProviderZipCode" shows up in the consumer field name and T1, the name of the Text Box in the HTML Form Web Part shows up in the provider field name..



3 comments:

  1. Hi,

    This is a very nice post and useful....I am facing an issue when am trying to connect to consumer filter....
    Do i need to do any configuration changes in web.config to achieve this.Please help me in this

    ReplyDelete