0

我正在尝试为具有名为的集合属性的 ASP.Net WebForms 开发一个简单的自定义 Web 控件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);
    }
}
4

1 回答 1

0

我能够通过进行以下 2 项更改来解决问题。

  1. 因为对于像 List 这样的集合,.Net 框架会自动显示一个合适的编辑器,所以我们不需要指定编辑器,因为集合是 List 类型的。所以我们不需要这个属性Editor(typeof(SubscriptionCollectionEditor), typeof(UITypeEditor))
  2. Subscriptions需要删除setter并且只有一个 get 应该在那里,如下面的代码所示。如果使用了 setter,那么它应该像第二个代码片段一样使用。但自动获取和设置不应与自定义 Web 控件中的集合属性一起使用

collections 属性的最终代码应如下所示,然后在设计时 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;
    }
}

使用 setter 的代码

[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;
    }
}
于 2016-05-21T17:28:26.603 回答