Редактор коллекций не сохраняет записи в пользовательской разметке веб-элемента управления в режиме конструктора в VS 2013?

Я пытаюсь разработать простой пользовательский веб-элемент управления для ASP.Net WebForms, который имеет свойство коллекций под названием Subscriptions,

Я могу успешно скомпилировать контрольный проект и без проблем добавить его из панели инструментов на страницу aspx.

Проблема в том, когда я добавляю записи для Subscriptions свойство с помощью редактора коллекций в режиме конструктора в Visual Studio 2013.

Я могу ввести несколько подписок, но когда я нажимаю кнопку "ОК" в редакторе коллекций, а затем возвращаюсь к свойству "Подписки" в режиме конструктора, оно пустое, хотя некоторые записи я уже вводил некоторое время назад.

Разметка пользовательского контроля в aspx

<cc1:WebControl1 ID="WebControl1" runat="server"></cc1:WebControl1>

Вопрос: Что не так с моим кодом, из-за которого коллекции не отображаются в разметке элемента управления в режиме конструктора?

Пользовательский веб-код управления

namespace WebControl1
{
    [ToolboxData("<{0}:WebControl1 runat=\"server\"> </{0}:WebControl1>")]
    [ParseChildren(true)]
    [PersistChildren(false)]
    public class WebControl1 : WebControl
    {
        [Bindable(true)]
        [Category("Appearance")]
        [DefaultValue("")]
        [Localizable(true)]
        public string Text
        {
            get
            {
                String s = (String)ViewState["Text"];
                return ((s == null) ? "[" + this.ID + "]" : s);
            }

            set
            {
                ViewState["Text"] = value;
            }
        }
        [
        Category("Behavior"),
        Description("The subscriptions collection"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
        Editor(typeof(SubscriptionCollectionEditor), typeof(UITypeEditor)),
        PersistenceMode(PersistenceMode.InnerDefaultProperty)
        ]
        public List<Subscription> Subscriptions { get; set; }

        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(Text);
        }
    }
}


[TypeConverter(typeof(ExpandableObjectConverter))]
public class Subscription
{
    private string name;
    private decimal amount;


    public Subscription()
        : this(String.Empty, 0.00m)
    {
    }

    public Subscription(string nm, decimal amt)
    {
        name = nm;
        amount = amt;
    }

    [
    Category("Behavior"),
    DefaultValue(""),
    Description("Name of subscription"),
    NotifyParentProperty(true),
    ]
    public String Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }

    [
    Category("Behavior"),
    DefaultValue("0.00"),
    Description("Amount for subscription"),
    NotifyParentProperty(true)
    ]
    public decimal Amount
    {
        get
        {
            return amount;
        }
        set
        {
            amount = value;
        }
    }
   }

public class SubscriptionCollectionEditor : System.ComponentModel.Design.CollectionEditor
{
    public SubscriptionCollectionEditor(Type type)
        : base(type)
    {
    }

    protected override bool CanSelectMultipleInstances()
    {
        return false;
    }

    protected override Type CreateCollectionItemType()
    {
        return typeof(Subscription);
    }
}

1 ответ

Решение

Я смог решить проблему, внеся следующие 2 изменения.

  1. Поскольку для таких коллекций, как List, платформа.Net автоматически отображает соответствующий редактор, поэтому нам не нужно указывать редактор, поскольку коллекция имеет тип List. Таким образом, нам не нужен этот атрибут Editor(typeof(SubscriptionCollectionEditor), typeof(UITypeEditor)),
  2. Сеттер для Subscriptions должен быть удален и должен быть только get, как в коде ниже. Если используется сеттер, то он должен использоваться как во втором фрагменте кода. Но автоматическое получение и установка не должны использоваться со свойством коллекции в пользовательском веб-элементе управления.

Окончательный код для свойства коллекций должен выглядеть следующим образом, и тогда коллекции не исчезнут, когда вы вернетесь к нему позже во время разработки VS 2013.

Код, который работает без установщика

private List<Subscription> list = null;

[Category("Behavior"),
 Description("The subscriptions collection"),
 DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
 PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public List<Subscription> SubscriptionList 
{ 
    get
    {
        if (lists == null)
        {
            lists = new List<Subscription>();
        }
        return lists;
    }
}

Код, который работает с сеттером

[Category("Behavior"),
 Description("The subscriptions collection"),            
 DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
 PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public List<Subscription> SubscriptionList 
{ 
    get
    {
        object s = ViewState["SubscriptionList"];
        if ( s == null)
        {
            ViewState["SubscriptionList"] = new List<Subscription>();
        }
        return (List<Subscription>) ViewState["SubscriptionList"];
    }
    set
    {
        ViewState["SubscriptionList"] = value;
    }
}
Другие вопросы по тегам