集合编辑器不会在 VS 2013 的设计视图中保留自定义 Web 控件标记中的条目?
Collections Editor is not persisting entries in custom web control markup in design view in VS 2013?
我正在尝试为 ASP.Net WebForms 开发一个简单的自定义 Web 控件,它有一个名为 Subscriptions
.
的集合 属性
我可以成功编译控件项目并将其从工具箱添加到 aspx 页面,没有任何问题。
问题是当我在 Visual Studio 2013 中使用设计视图中的集合编辑器为 Subscriptions
属性 添加条目时。
我可以输入多个订阅,但是当我点击集合编辑器的确定按钮然后返回到设计视图中的订阅 属性 时,即使我刚才输入了一些条目,它还是空的。
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);
}
}
我通过进行以下 2 处更改解决了问题。
- 因为像List这样的集合,.Net框架会自动显示一个合适的编辑器,所以我们不需要指定编辑器,因为集合是List类型的。所以我们不需要这个属性
Editor(typeof(SubscriptionCollectionEditor), typeof(UITypeEditor))
.
Subscriptions
的 setter 需要删除,只有一个 get 应该在那里,如下面的代码所示。如果使用了 setter,那么它应该像在第二个代码片段中那样使用。 但自动获取和设置不应与自定义 Web 控件中的集合 属性 一起使用。
集合 属性 的最终代码应如下所示,稍后在设计时 VS 2013 中添加一个 returns 时集合不会消失。
没有 setter
的代码
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;
}
}
我正在尝试为 ASP.Net WebForms 开发一个简单的自定义 Web 控件,它有一个名为 Subscriptions
.
我可以成功编译控件项目并将其从工具箱添加到 aspx 页面,没有任何问题。
问题是当我在 Visual Studio 2013 中使用设计视图中的集合编辑器为 Subscriptions
属性 添加条目时。
我可以输入多个订阅,但是当我点击集合编辑器的确定按钮然后返回到设计视图中的订阅 属性 时,即使我刚才输入了一些条目,它还是空的。
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);
}
}
我通过进行以下 2 处更改解决了问题。
- 因为像List这样的集合,.Net框架会自动显示一个合适的编辑器,所以我们不需要指定编辑器,因为集合是List类型的。所以我们不需要这个属性
Editor(typeof(SubscriptionCollectionEditor), typeof(UITypeEditor))
. Subscriptions
的 setter 需要删除,只有一个 get 应该在那里,如下面的代码所示。如果使用了 setter,那么它应该像在第二个代码片段中那样使用。 但自动获取和设置不应与自定义 Web 控件中的集合 属性 一起使用。
集合 属性 的最终代码应如下所示,稍后在设计时 VS 2013 中添加一个 returns 时集合不会消失。
没有 setter
的代码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;
}
}