1-888-365-2779
+1-888-365-2779
Try Now
More in this section

Forums / Developing with Sitefinity / Values not saving in uploaded UserControl

Values not saving in uploaded UserControl

9 posts, 0 answered
  1. Solomon
    Solomon avatar
    10 posts
    Registered:
    12 Feb 2008
    27 Jun 2009
    Link to this post
    I have a user control that I created that contains a GenericContent HTML editor and a few simple string and bool properties. The problem is when I add content to the GenericContent control, it will not save my other values in the Properties tab (in fact, it will switch to the Properties tab, it will switch, but it will not be highlighted). This only seems to happen if I have content in the GenericContent control, otherwise it saves fine. Very strange. Any help would be greatly appreciated.

    I have posted a few screen shots here:
    The generic content control.
    http://staging.deepblue.com/general/1.jpg

    After the Properties tab is selected. These values are not saved. Notice it is not highlighted because there is content in the generic control control - otherwise it would be highlighted.
    http://staging.deepblue.com/general/2.jpg

    Here is the ascx:
    <div runat="server" id="divAccordionPanel">
        <div class="AccordionPanelTab">
            <asp:placeholder id="phTitle" runat="server"></asp:placeholder>
        </div>
        <div runat="server" id="divAccordionPanelContent" class="AccordionPanelContent">
            <div class="container">
                <sfweb:genericcontent runat="server" id="GenericContent1" />
            </div>
        </div>
    </div>

    Here is the .cs
    using System;
    using System.ComponentModel;
    using System.Web.UI;
    using Telerik.Cms;
    using Telerik.Cms.Web.UI;

    public partial class CustomUserControls_AccordionPanel : UserControl, IContentContainer
    {
        protected Nullable<int> _height;
        protected bool _open = false;
        protected string _title = "";

        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        public bool Open
        {
            get { return _open; }
            set { _open = value; }
        }

        public Nullable<int> Height
        {
            get { return _height; }
            set { _height = value; }
        }

        #region IContentContainer Members

        [Browsable(false)]
        [WebEditor("Telerik.Cms.Engine.WebControls.HtmlContentEditor, Telerik.Cms.Engine")]
        [TypeConverter(typeof (StringConverter))]
        public object Content
        {
            get { return GenericContent1.Content; }
            set { GenericContent1.Content = value.ToString(); }
        }

        public string ProviderName
        {
            get { return GenericContent1.ProviderName; }
            set { GenericContent1.ProviderName = value; }
        }

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            phTitle.Controls.Add(new LiteralControl(Title));

            if (_height != null)
            {
            }

            if (Open)
            {
                divAccordionPanel.Attributes.Add("class", "AccordionPanel AccordionPanelOpen");
                if (_height != null)
                {
                    divAccordionPanelContent.Attributes.Add("style", string.Format("height: {0}px;", _height.ToString()));
                }
            }
            else
            {
                divAccordionPanel.Attributes.Add("class", "AccordionPanel AccordionPanelClosed");
                divAccordionPanelContent.Attributes.Add("style", "height: 0px; display: none;");
            }
        }
    }
  2. Solomon
    Solomon avatar
    10 posts
    Registered:
    12 Feb 2008
    29 Jun 2009
    Link to this post
    Ivan or any of the Sitefinity crew - any ideas on this?
  3. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    30 Jun 2009
    Link to this post
    Hi Solomon,

    The problem appears when you save the control for the first time. Afterwords the property is saved correctly and the control works. It seems that the problem comes from the designer when Generic Content is used in the context of a User control.
    There are two options that I could suggest.

    1. Create a Custom control as this one below:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Web; 
    using Telerik.Cms.Engine.WebControls; 
    using System.Web.UI.WebControls; 
    using System.ComponentModel; 
     
    /// <summary> 
    /// Summary description for CustomGenericContentControl 
    /// </summary> 
    ///  
     
    [ToolboxItem(typeof(CustomGenericContentControl))] 
    public class CustomGenericContentControl : GenericContent 
        public CustomGenericContentControl() 
        { 
        } 
        [Browsable(true)] 
        [Category("TESTCONTROL")] 
        public string Title 
        { 
            get 
            { 
                object o = this.ViewState["title"]; 
                if (o == null
                    return null
                return (string)o; 
            } 
            set 
            { 
                this.ViewState["title"] = value; 
            } 
        } 
        [Browsable(true)] 
        [Category("TESTCONTROL")] 
        public bool Open 
        { 
            get 
            { 
                object o = this.ViewState["open"]; 
                if (o == null
                    return false
                return (bool)o; 
            } 
            set 
            { 
                this.ViewState["open"] = value; 
            } 
        } 
        // test property
        [Browsable(false)] 
        [Category("TESTCONTROL")] 
        public string OldContent 
        { 
            get 
            { 
                object o = this.ViewState["oldContent"]; 
                if (o == null
                    return null
                return (string)o; 
            } 
            set 
            { 
                this.ViewState["oldContent"] = value; 
            } 
        } 
     
     
        protected override void Render(System.Web.UI.HtmlTextWriter writer) 
        { 
            if (Open) 
            { 
                writer.Write(this.Title); 
                base.Render(writer); 
            } 
            else 
            { 
                writer.Write(this.Title); 
            } 
        } 
     

    2. Keep using your user control, but you will have in mind that the property values will be persisted on your second attempt to save the control.

    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  4. Solomon
    Solomon avatar
    10 posts
    Registered:
    12 Feb 2008
    01 Jul 2009
    Link to this post
    Thanks for getting back to me, Ivan. I am a little confused how this control is similar to my existing control. Will this render a generic content control with the additional public properties? How about the render method. How do I specify the output of the generic content here? Why is it named "oldContent" and how does this factor in?

    All I need to do is output some opening html, then the generic content, and then some closing html. The opening html will vary based on the values of the public properties.

    Your help is greatly appreciated. Talk to you soon.

    Solomon
  5. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    01 Jul 2009
    Link to this post
    Hi Solomon,

    I am not sure whether you have tried the code I sent. This is a custom control that inherits from GenericContent control. I have create two public properties Title and Open which value I save in ViewState. These properties can be edited through control Edit mode. You can add the same property for _height.
    As you can see oldContent was added just for testing purposes - // test property. It is never used.
    In Render method we check whether the Open is true. If so we show the title and call the base. If the property is false we show only the title and hide the content( it is the same as display: none;).

    I hope this helps.

    Kind regards,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  6. Solomon
    Solomon avatar
    10 posts
    Registered:
    12 Feb 2008
    07 Jul 2009
    Link to this post
    Ivan,

    I am a little trouble creating and uploading my custom control into Sitefinity.

    I have created a new class project (called CustomControls) and added my code to AccordionPanel.cs (also setting project references to Telerik.CMS, Telerik.CMS.Engine, Telerik.CMS.Web.UI, and Telerik.Framework).

    Here is the code:
    using System; 
    using System.Collections.Generic; 
    using System.Web; 
    using Telerik.Cms.Engine.WebControls; 
    using System.Web.UI.WebControls; 
    using System.ComponentModel; 
     
    /// [ToolboxItem(typeof(AccordionPanel))]  
    public class AccordionPanel : GenericContent 
        public AccordionPanel() 
        { 
        } 
     
        [Browsable(true)] 
        public string Title 
        { 
            get 
            { 
                object o = this.ViewState["title"]; 
                if (o == null) 
                    return null; 
                return (string)o; 
            } 
            set 
            { 
                this.ViewState["title"] = value; 
            } 
        } 
     
        [Browsable(true)] 
        public bool Open 
        { 
            get 
            { 
                object o = this.ViewState["open"]; 
                if (o == null) 
                    return false; 
                return (bool)o; 
            } 
            set 
            { 
                this.ViewState["open"] = value; 
            } 
        } 
     
        protected override void Render(System.Web.UI.HtmlTextWriter writer) 
        { 
            System.Text.StringBuilder builder = new System.Text.StringBuilder(); 
     
            if (Open) 
            { 
                builder.Append("<div class=\"AccordionPanel AccordionPanelOpen\">"); 
            } 
            else 
            { 
                builder.Append("<div class=\"AccordionPanel\">"); 
            } 
     
            builder.Append(string.Format("<div class=\"AccordionPanelTab\">{0}</div>", Title)); 
            builder.Append("<div class=\"AccordionPanelContent\">"); 
            writer.Write(builder.ToString()); 
     
            base.Render(writer); 
     
            writer.Write("</div></div>"); 
        } 

    When I upload the control to Sitefinity by selecting the compiled dll from this project, I get the following error.

    Unable to cast object of type 'Telerik.Cms.Engine.WebControls.GenericContentToolboxItem' to type 'System.Drawing.Design.ToolboxItem'.

    Any ideas?

    Thanks for all your help!

    Solomon
  7. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    08 Jul 2009
    Link to this post
    Hello Solomon,

    1. Add the following logic to the AccordionPanel class.

     
        [ToolboxItem(typeof(AccordionPanelToolBoxItem))] 
        public class AccordionPanel : GenericContent 

    2. Create ToolBoxItem.

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Drawing; 
     
    namespace ClassLibrary1 
        public class AccordionPanelToolBoxItem : System.Drawing.Design.ToolboxItem 
        { 
            public AccordionPanelToolBoxItem() 
                : base(typeof(AccordionPanel)) 
            { 
                base.DisplayName = "TEST"
                base.Description = "TEST"
                base.Company = "Custom"
            } 
     
     
        } 

    3. Compile and upload.

    Greetings,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  8. Adam
    Adam avatar
    33 posts
    Registered:
    23 Feb 2009
    10 Nov 2009
    Link to this post
    Ivan,

    I'm having the same problem, but it does not save properties after the control is first added. Here is my code sample.

    codebehind:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Telerik.Cms;
    using Telerik;
    using Telerik.Cms.Engine.WebControls;
    using System.ComponentModel;
    using Telerik.Cms.Web.UI;
    using Telerik.Cms.Engine;

    [DefaultProperty("Title")]
    public partial class App_Custom_Callouts_ContentCallout : System.Web.UI.UserControl
    {


        protected void Page_Load(object sender, EventArgs e)
        {
            //this.contentBody.InnerHtml = this.ContentBody;
            this.contentTitle.InnerText = this.Title;

            if (!string.IsNullOrEmpty(this.Image))
            {
                this.imgCalloutWrapper.Visible = true;
                this.imgCallout.Src = this.GetItemUrl(this.Image);
            }
            else
            {
                this.imgCalloutWrapper.Visible = false;
            }

            if (!string.IsNullOrEmpty(this.LearnMoreUrl))
            {
                this.learnMoreWrapper.Visible = true;
                this.learnMoreLink.HRef = this.ResolveUrl(this.LearnMoreUrl);
            }
            else
            {
                this.learnMoreWrapper.Visible = false;
            }
        }

        [Category("Main")]
        public string Title { get; set; }

        [Category("Main")]
        [WebEditor("Telerik.Cms.Web.UI.CmsUrlWebEditor")]
        public string LearnMoreUrl { get; set; }

        [Category("Main")]
        [WebEditor("Telerik.Libraries.WebControls.ImageSelector")]
        public string Image
        {
            get { return this.ViewState["image_path"] == null ? "" : this.ViewState["image_path"].ToString(); }
            set { this.ViewState["image_path"] = value; }
        }


        [Browsable(false)]
        public override bool EnableTheming
        {
            get
            {
                return base.EnableTheming;
            }
            set
            {
                base.EnableTheming = value;
            }
        }

        [Browsable(false)]
        public override bool EnableViewState
        {
            get
            {
                return base.EnableViewState;
            }
            set
            {
                base.EnableViewState = value;
            }
        }

        [Browsable(false)]
        public override bool Visible
        {
            get
            {
                return base.Visible;
            }
            set
            {
                base.Visible = value;
            }
        }


        private string GetItemUrl(string val)
        {
            if (val.StartsWith("~/"))
                return this.ResolveUrl(val);

            if (val.StartsWith("["))
            {
                int idx = val.IndexOf("]");
                string provider = val.Substring(1, idx - 1);
                string strId = val.Substring(idx + 1);
                Guid id = new Guid(strId);
                if (ContentManager.Providers.ContainsKey(provider))
                {
                    IContent cnt = ContentManager.Providers[provider].GetContent(id);
                    if (cnt != null)
                        return VirtualPathUtility.ToAbsolute(cnt.UrlWithExtension, this.Context.Request.ApplicationPath);
                }
            }
            return val.ToString();
        }



        #region IContentContainer Members

        [Browsable(false)]
        [WebEditor("Telerik.Cms.Engine.WebControls.HtmlContentEditor, Telerik.Cms.Engine")]
        [TypeConverter(typeof(StringConverter))]
        public object Content
        {
            get
            {
                return this.GenericContent1.Content;
            }
            set
            {
                this.GenericContent1.Content = (string)value;
            }
        }

        public string ProviderName
        {
            get
            {
                return this.GenericContent1.ProviderName;
            }
            set
            {
                this.GenericContent1.ProviderName = value;
            }
        }
        #endregion
    }


    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="ContentCallout.ascx.cs"
        Inherits="App_Custom_Callouts_ContentCallout" %>
    <%@ Register Assembly="Telerik.Cms.Engine" Namespace="Telerik.Cms.Engine.WebControls"
        TagPrefix="sfWeb" %>
    <div class="callout">
        <div class="title" runat="server" id="contentTitle">
        </div>
        <div class="body-wrapper">
            <div class="image" runat="server" id="imgCalloutWrapper">
                <img runat="server" id="imgCallout" src="resources/img/callout-1.gif" alt="callout image" />
            </div>
            <div class="body">
                <sfWeb:GenericContent runat="server" ID="GenericContent1" />
                <div class="learn-more" runat="server" id="learnMoreWrapper">
                    <a href="#" runat="server" id="learnMoreLink">LEARN MORE</a></div>
            </div>
        </div>
    </div>

  9. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    12 Sep 2017
    10 Nov 2009
    Link to this post
    Hi Adam,

    You should use a custom control not an user control as suggested in the previous posts. Create a custom control that inherits from GenericContent class.

    Sincerely yours,
    Ivan Dimitrov
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Register for webinar
9 posts, 0 answered