为什么MessageBox和CheckBox在更改First属性的值时会在Design-Time中出现,而在将项目添加到Second时却不会出现?
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;
}
}
当我将Collection更改为List时,情况相同... 保留值(或在第二种情况下添加到Collection),设计器为InitializeComponent()生成代码。
在@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;
}
}
现在的问题是:当我在编辑器中添加let&#39; s说第三项时,它只绘制一个复选框,但应绘制3个复选框... 此外,在调试中,我看到foreach循环经过3次:第一次收集有1个项目,第二次收集有2个项目,第三次收集有3个项目,但最后我只看到_checkboxPanel中的一个复选框。
答案 0 :(得分:1)
因为只有在替换整个集合时才会执行Second
属性的setter。添加/删除项目时,getter会返回您的集合实例(_second
),并在该对象实例上调用Add
/ Remove
方法。
如果要对元素添加/删除执行检查,请改为创建自定义集合类型:
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);
}
}
答案 1 :(得分:1)
您现在使用的内置集合编辑器仅更改集合对象的内容。哪个工作正常,但根本没有调用你的二传手。换句话说,它从不创建新的集合对象,也不知道如何做到这一点。
要调用属性setter,必须创建自己的UITypeEditor并让它从EditValue()方法重写返回一个新集合。很容易做到,首先添加对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);
}
}
您可能希望稍微改进一下,比如实现自己的编辑器UI,这样所有这些bool都更容易理解。