[英]WinForms - UserControl - List<bool> an Collection<bool> as Browseable Property of UserControl
Why the MessageBox and CheckBox apprears in Design-Time when changing value of the First property and do not when adding item to Second? 为什么在更改First属性的值时,而在将项目添加到Second属性时,MessageBox和CheckBox在设计时会增加?
private string _first;
[Description(""), Category("GostcompSettings"), DefaultValue("27017")]
public string First
{
get { return __first; }
set
{
_searchAreasChceckBoxList.Clear();
pPanelWithCheckboxies.Controls.Clear();
int x = 10;
int y = 10;
CheckBox _tempCheck = new CheckBox();
_tempCheck.Checked = true;
_tempCheck.Location = new Point(x, y);
_searchAreasChceckBoxList.Add(_tempCheck);
pPanelWithCheckboxies.Controls.Add(_tempCheck);
MessageBox.Show("zmiana");
_first = value;
}
}
private Collection<bool> _second= new Collection<bool>();
[Description(""), Category("*")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Collection<bool> Second
{
get
{
return _second;
}
set
{
_searchAreasChceckBoxList.Clear();
pPanelWithCheckboxies.Controls.Clear();
int x = 10;
int y = 10;
CheckBox _tempCheck = new CheckBox();
_tempCheck.Checked = true;
_tempCheck.Location = new Point(x, y);
_searchAreasChceckBoxList.Add(_tempCheck);
pPanelWithCheckboxies.Controls.Add(_tempCheck);
MessageBox.Show("*");
_second= value;
}
}
It's the same scenario when I change Collection to List... Values are kept (or added to Collection in Second case) and designer generate code for InitializeComponent(). 当我将Collection更改为List时,情况相同。值保留(或在第二种情况下添加到Collection中),设计器为InitializeComponent()生成代码。
EDIT after @taffer answear @taffer answear之后编辑
public class SearchAreaInfo
{
public SearchAreasEnum searchArea
{
get; set;
}
}
public class SearchAreaInfoCollection : Collection<SearchAreaInfo>
{
private Panel _checkboxParent;
public SearchAreaInfoCollection(Panel checkboxParent) : base()
{
_checkboxParent = checkboxParent;
}
// called on Add/Insert
protected override void InsertItem(int index, SearchAreaInfo item)
{
base.InsertItem(index, item);
RepaintChackboxPanel();
}
// called on Remove/RemoveAt
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
RepaintChackboxPanel();
}
// called when an element is set by the indexer
protected override void SetItem(int index, SearchAreaInfo item)
{
base.SetItem(index, item);
RepaintChackboxPanel();
}
private void RepaintChackboxPanel()
{
//_searchAreasChceckBoxList.Clear();
_checkboxParent.Controls.Clear();
int x = 0;
int y = 0;
foreach (var item in this)
{
CheckBox _tempCheck = new CheckBox();
_tempCheck.Checked = true;
_tempCheck.Location = new Point(x, y);
_tempCheck.BringToFront();
//_searchAreasChceckBoxList.Add(_tempCheck);
_checkboxParent.Controls.Add(_tempCheck);
x += 5;
y += 5;
}
_checkboxParent.Invalidate();
}
}
private SearchAreaInfoCollection _searchAreas;
[Description(""), Category("GostcompSettings")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public SearchAreaInfoCollection SearchAreas
{
get
{
return _searchAreas;
}
}
Now the prooblem is that: when I add let's say third item to the collection in Editor it draws only one checkbox but should draw 3 checkboxes... Moreover in debugging I see that foreach loop goes then 3 times: 1st collection has 1 item , 2nd time collection has 2 items and third time collection has 3 items, but finally I see just one checkbox in _checkboxPanel. 现在的问题是:当我在编辑器中向集合添加第三个项目时,它仅绘制一个复选框,但应绘制3个复选框...此外,在调试中,我看到foreach循环进行了3次:第一个集合具有1个项目,第二次收集有2个项目,第三次收集有3个项目,但是最后我在_checkboxPanel中仅看到一个复选框。
Because the setter of Second
property is executed only when you replace the whole collection. 因为
Second
属性的setter仅在替换整个集合时才执行。 When you add/remove an item, the getter returns your collection instance ( _second
), and the Add
/ Remove
method will be called on that object instance. 添加/删除项目时,getter返回您的集合实例(
_second
),并且将在该对象实例上调用Add
/ Remove
方法。
If you want to perform checks on element addition/removal, create a custom collection type instead: 如果要执行元素添加/删除的检查,请创建一个自定义集合类型:
public class MyBoolCollection: Collection<bool>
{
// called on Add/Insert
protected override void InsertItem(int index, bool item)
{
// do some checks here
base.InsertItem(index, item);
}
// called on Remove/RemoveAt
protected override void RemoveItem(int index)
{
// do some checks here
base.RemoveItem(index, item);
}
// called when an element is set by the indexer
protected override void SetItem(int index, bool item)
{
// do some checks here
base.SetItem(index, item);
}
}
The built-in collection editor that you are using now only changes the content of your collection object. 您正在使用的内置集合编辑器现在仅更改集合对象的内容 。 Which works fine, but does not get your setter called at all.
哪个工作正常,但根本不会调用设置程序。 In other words, it never creates a new collection object, nor does it know how to do that.
换句话说,它永远不会创建新的集合对象,也不知道该怎么做。
To get your property setter called, you have to create your own UITypeEditor and have it return a new collection from its EditValue() method override. 要调用属性设置器,您必须创建自己的UITypeEditor并使其从其EditValue()方法重写中返回一个新集合。 Pretty easy to do, first add a reference to System.Design, then make your code look similar to this:
相当容易做到,首先添加对System.Design的引用,然后使您的代码类似于以下内容:
using System.Drawing.Design;
...
[Editor(typeof(MyEditor), typeof(System.Drawing.Design.UITypeEditor))]
public Collection<bool> Second {
// etc...
}
private class MyEditor : UITypeEditor {
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) {
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {
var editor = new System.ComponentModel.Design.CollectionEditor(typeof(Collection<bool>));
var retval = (Collection<bool>)editor.EditValue(context, provider, value);
return new Collection<bool>(retval);
}
}
You probably want to improve this a bit, like implementing your own editor UI so all of those bools are easier to interpret. 您可能需要进行一些改进,例如实现自己的编辑器UI,以便更轻松地解释所有这些布尔。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.