Widget with a custom designer and string[] property

Posted by Community Admin on 03-Aug-2018 18:37

Widget with a custom designer and string[] property

All Replies

Posted by Community Admin on 24-Mar-2011 00:00

How can I manage widget string[] property by a custom designer? I've tried to do following:


 public class TextControl : TextControlBase
     private const string TemplateName = "Controls.Resources.Templates.TextControl.ascx";
     protected override void InitializeControls(GenericContainer container)
         TextBox1.Text = this.Text;
         if (this.Test != null)
             TextBox2.Text = this.Test[0];
    public string Text get; set;
     public string[] Test get; set;
     protected override string LayoutTemplateName
             return TemplateName;
     protected virtual TextBox TextBox1
             return base.Container.GetControl<TextBox>("TextBox1", true);
     protected virtual TextBox TextBox2
             return base.Container.GetControl<TextBox>("TextBox2", true);

Widget's Template:
<%@ Control Language="C#" %>
<asp:TextBox runat="server" ID="TextBox1" />
<asp:TextBox runat="server" ID="TextBox2" />

Custom Designer:
public class TextControlDesigner : ControlDesignerBase
       private const string TemplateName = "Controls.Resources.Templates.TextControlDesigner.ascx";
       private const string ScriptReference = "Controls.Resources.JavaScript.TextControlDesigner.js";
       protected override void InitializeControls(GenericContainer container)
           base.DesignerMode = ControlDesignerModes.Simple;
       protected override string LayoutTemplateName
               return TemplateName;
       public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
           var res = new List<ScriptReference>(base.GetScriptReferences());
           var assemblyName = this.GetType().Assembly.GetName().ToString();
           res.Add(new ScriptReference(ScriptReference, assemblyName));
           return res.ToArray();

Control designer's template:
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI"
    TagPrefix="sitefinity" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<div class="sfContentViews">
    <div id="TextControlOptions">
            Fine tune your Text control
            <label for="text">
            <input type="text" id="text" class="sfTxt" />
            <label for="test">
            <input type="text" id="test" class="sfTxt" />        

and custom designer's .js file:
Controls.Navigation.TextControlDesigner = function (element)
   Controls.Navigation.TextControlDesigner.initializeBase(this, [element]);
    this._parentDesigner = null;
    this._googleAnalyticsCodeTextField = null;
    this._scriptEmbedPositionChoiceField = null;
    this._toogleGroupSettingsDelegate = null;
Controls.Navigation.TextControlDesigner.prototype =
    initialize: function ()
        Controls.Navigation.TextControlDesigner.callBaseMethod(this, 'initialize');
        this._toogleGroupSettingsDelegate = Function.createDelegate(this, function ()
    dispose: function ()
       Controls.Navigation.TextControlDesigner.callBaseMethod(this, 'dispose');
    refreshUI: function ()
        var data = this._propertyEditor.get_control();
        if ((data.Test !== null) && (typeof (data.Test) !== 'undefined'))
    applyChanges: function ()
        var controlData = this._propertyEditor.get_control();
        controlData.Text = jQuery("#text").val();
        controlData.Test = new Array();
        controlData.Test[0] = '1';
Controls.Navigation.TextControlDesigner.registerClass('Controls.Navigation.TextControlDesigner', Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesignerBase);
if (typeof (Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
* I've removed the assembly name from a code.

When I had only a string Text property, I was able to save it by pressing a Save button. But when I added the string[] Test property every attempt to save is finished by following message at Firebug's console:

Error Status Code: 'InternalServerError'
Details: There was an error deserializing the object of type Telerik.Sitefinity.Modules.Pages.Web.Services.Model.WcfControlProperty[]. End element 'PropertyValue' from namespace '' expected. Found element 'item' from namespace ''.

Posted by Community Admin on 28-Mar-2011 00:00

Hi Vyacheslav,

Generally you should deserialize and serialize the object on the client using  Sys.Serialization.JavaScriptSerializer

All the best,
Ivan Dimitrov
the Telerik team

Posted by Community Admin on 30-Mar-2011 00:00

Hi Ivan,
Thank you for your answer.
I've tried to do following at the designer's js code:

applyChanges: function ()
      var controlData = this._propertyEditor.get_control();
      controlData.Text = jQuery("#text").val();
      var test = new Array();
      test[0] = '1';
      test[1] = '2';
      console.log("test: %o", test);
      controlData.Test = Sys.Serialization.JavaScriptSerializer.serialize(test);
      console.log("serialized test: %o", Sys.Serialization.JavaScriptSerializer.serialize(test));

Also, I've added the [TypeConverter(typeof(StringArrayConverter))] attribute of the TextControl.Test property and saving is working properly now. My widget base class:

namespace HEH.WebSite.EducationalPortal.Controls.ControlBase

    using System.ComponentModel;
    using Converters;
    using Telerik.Sitefinity.Web.UI;

    public abstract class TextControlBase : SimpleView
        public string Text get; set;

        public string[] Test get; set;

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design.Serialization;
    using System.Globalization;
    using Newtonsoft.Json;
    public class StringArrayConverter : TypeConverter
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
            return ((sourceType == typeof(string)) || base.CanConvertFrom(context, sourceType));
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
            return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
            if (value is string)
                return JsonConvert.DeserializeObject<string[]>(value as string);
            return base.ConvertFrom(context, culture, value);
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
                                         Type destinationType)
            if (value is string[])
                return JsonConvert.SerializeObject(value);
            return base.ConvertTo(context, culture, value, destinationType);

Thank you for your help.

This thread is closed