Question

I'm trying to write a webpart that basically pulls data from a list and displays it to the user. There is a feature news list where one of the columns holds a URL to an image. The web part should get the 3 most recent feature news items and create three image controls on the page. These image controls can be scrolled through by clicking on the buttons 1,2,3. (Ie, clicking on 2 will set the Visible property of image 1 and image 3 to false).

I have managed to implement AJAX here, but am now trying to use the UpdatePanelAnimationExtender from the AJAX Control Toolkit.

I have followed all instructions on how to use the toolkit, add it to the GAC, add a safe assembly, etc, and have gotten past all the errors besides this one:

"Page cannot be null. Please ensure that this operation is being performed in the context of an ASP.NET request"

My complete code below:

    using System; using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Web.UI; 
using System.Web.UI.WebControls.WebParts; 
using System.Web.UI.WebControls;
 using System.Web.Extensions; 
using Microsoft.SharePoint; 
using Microsoft.SharePoint.Utilities; 
using System.ComponentModel; 
using AjaxControlToolkit;

namespace FeatureNewsWebpartFeature {
    [Guid("7ad4b959-d494-4e85-b164-4e4231692b8b")]
    public class FeatureNewsWebPart : Microsoft.SharePoint.WebPartPages.WebPart
    {
        private bool _error = false;
        private string _listName = null;
        private string _imageColumn = null;
        Image image1;
        Image image2;
        Image image3;
        UpdatePanelAnimationExtender upAnimator;


        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("List Connection Settings")]
        [WebDisplayName("List Name")]
        [WebDescription("Enter the name of the news list")]
        public string ListName
        {
            get
            {
                if (_listName == null)
                {
                    _listName = "News";
                }
                return _listName;
            }
            set { _listName = value; }
        }

        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("List Connection Settings")]
        [WebDisplayName("Image Column Name")]
        [WebDescription("Enter the column name of the ArtfulBits Image Upload column")]
        public string ImageUrlColumn
        {
            get
            {
                if (_imageColumn == null)
                {
                    _imageColumn = "Feature Image";
                }
                return _imageColumn;
            }
            set { _imageColumn = value; }
        }


        public FeatureNewsWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {
                    base.CreateChildControls();



                    //Create script manager
                    if (ToolkitScriptManager.GetCurrent(this.Page) == null)
                    {

                        ToolkitScriptManager scriptHandler = new ToolkitScriptManager();
                        scriptHandler.ID = "scriptHandler";
                        scriptHandler.EnablePartialRendering = true;
                        this.Controls.Add(scriptHandler);
                    }


                    //Create update panel
                    System.Web.UI.UpdatePanel imageUpdatePanel = new System.Web.UI.UpdatePanel();
                    imageUpdatePanel.ID = "imageUpdatePanel";
                    imageUpdatePanel.UpdateMode = UpdatePanelUpdateMode.Conditional;
                    this.Controls.Add(new LiteralControl("<div id=\"updateContainer\">"));
                    this.Controls.Add(imageUpdatePanel);
                    this.Controls.Add(new LiteralControl("</div>"));




                    //Make SPSite object and retrieve the three most recent feature news items
                    SPSite site = SPContext.Current.Site;
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList oList = web.Lists[ListName];
                        SPQuery oQuery = new SPQuery();
                        oQuery.RowLimit = 3;
                        oQuery.Query = "<OrderBy>" +
                            "<FieldRef Name='Modified' Ascending='False' /></OrderBy>" +
                            "<Where>" +
                            "<Eq>" +
                            "<FieldRef Name='ContentType' />" +
                            "<Value Type='Choice'>Feature News Item</Value>" +
                            "</Eq>" +
                            "</Where>";


                        oQuery.ViewFields = string.Concat(
                            "<FieldRef Name='Feature_x0020_Image' />" +
                            "<FieldRef Name='Feature_x0020_Order' />");


                        image1 = new Image();
                        image2 = new Image();
                        image3 = new Image();

                        //For each item, extract image URL and assign to image object
                        SPListItemCollection items = oList.GetItems(oQuery);
                        foreach (SPListItem oListItem in items)
                        {
                            string url = oListItem["Feature_x0020_Image"].ToString();
                            url = url.Substring(url.IndexOf("/Lists"));
                            url = url.Remove(url.IndexOf(";#"));

                            switch (oListItem["Feature_x0020_Order"].ToString())
                            {
                                case "1":
                                    image1.ImageUrl = url;
                                    break;
                                case "2":
                                    image2.ImageUrl = url;
                                    break;
                                case "3":
                                    image3.ImageUrl = url;
                                    break;
                                default:
                                    //ERROR
                                    break;
                            }
                        }


                        if (!(Page.IsPostBack))
                        {
                            image1.Visible = true;
                            image2.Visible = false;
                            image3.Visible = false;
                        }


                        imageUpdatePanel.ContentTemplateContainer.Controls.Add(image1);
                        imageUpdatePanel.ContentTemplateContainer.Controls.Add(image2);
                        imageUpdatePanel.ContentTemplateContainer.Controls.Add(image3);


                        //Create animation for update panel
                        upAnimator = new UpdatePanelAnimationExtender();
                        upAnimator.ID = "upAnimator";
                        upAnimator.TargetControlID = imageUpdatePanel.ID;
                        const string xml = "<OnUpdating>" +
                            "<Parallel duration=\".25\" Fps=\"30\">" +
                            "<FadeOut AnimationTarget=\"updateContainer\" minimumOpacity=\".2\" />" +
                            "</OnUpdating>" +
                            "<OnUpdated>" +
                            "<FadeIn AnimationTarget=\"updateContainer\" minimumOpacity=\".2\" />" +
                            "</OnUpdated>";

                        Animation.Parse(xml, upAnimator);
                        this.Controls.Add(upAnimator);

                        Button b1 = new Button();
                        b1.ID = "b1i";
                        b1.Click += new EventHandler(b1_Click);
                        b1.Text = "Image 1";


                        Button b2 = new Button();
                        b2.ID = "b2i";
                        b2.Click += new EventHandler(b2_Click);
                        b2.Text = "Image 2";


                        Button b3 = new Button();
                        b3.ID = "b3i";
                        b3.Click += new EventHandler(b3_Click);
                        b3.Text = "Image 3";

                        this.Controls.Add(b1);
                        this.Controls.Add(b2);
                        this.Controls.Add(b3);

                        AsyncPostBackTrigger tr1 = new AsyncPostBackTrigger();
                        tr1.ControlID = b1.ID;
                        //tr1.EventName = "Click";
                        imageUpdatePanel.Triggers.Add(tr1);


                        AsyncPostBackTrigger tr2 = new AsyncPostBackTrigger();
                        tr2.ControlID = b2.ID;
                        //tr2.EventName = "Click";
                        imageUpdatePanel.Triggers.Add(tr2);


                        AsyncPostBackTrigger tr3 = new AsyncPostBackTrigger();
                        tr3.ControlID = b3.ID;
                        //tr3.EventName = "Click";
                        imageUpdatePanel.Triggers.Add(tr3);


                    }
                }
                catch (Exception ex)
                {

                    HandleException(ex);
                }
            }
        }

        void b1_Click(object sender, EventArgs e)
        {
            image1.Visible = true;
            image2.Visible = false;
            image3.Visible = false;
        }
        void b2_Click(object sender, EventArgs e)
        {
            image1.Visible = false;
            image2.Visible = true;
            image3.Visible = false;
        }
        void b3_Click(object sender, EventArgs e)
        {
            image1.Visible = false;
            image2.Visible = false;
            image3.Visible = true;
        }
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

        }

        protected override void Render(HtmlTextWriter writer)
        {


            base.Render(writer);
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            if (!_error)
            {
                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    // Your code here...
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }
    } }
Was it helpful?

Solution

Here's a related question though being asked in the context of SP 2010, it's still directly applicable given the solution.

We have a CQWP on our MOSS farm that does essentially the same thing: reads items from a list using jQuery and the SPServices plugin and animates slider changes. The most difficult part of the process is actually tweaking the look, if I remember correctly. Once you have the right pieces, putting it together is a snap.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top