WinForms - UserControl - List<一个Collection< bool>作为UserContr
本文关键字:UserContr bool 作为 一个 UserControl List WinForms Collection | 更新日期: 2023-09-27 18:08:10
为什么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;
}
}
这是相同的场景,当我改变集合列表…值被保留(或在第二种情况下添加到集合),设计器为InitializeComponent()生成代码。
在@taffer answer后编辑
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;
}
}
现在的问题是:当我在编辑器中添加第三个项目时,它只绘制一个复选框,但应该绘制3个复选框…此外,在调试中,我看到foreach循环进行了3次:第一次收集有1项,第二次收集有2项,第三次收集有3项,但最后我在_checkboxPanel中只看到一个复选框。
因为只有在替换整个集合时才会执行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);
}
}
您现在使用的内置集合编辑器只更改集合对象的内容。它工作得很好,但根本不会调用setter。换句话说,它从不创建新的集合对象,也不知道如何创建。
要调用属性设置器,您必须创建自己的UITypeEditor,并让它从其EditValue()方法覆盖返回一个新集合。很容易做到,首先添加一个对System的引用。设计,然后使你的代码看起来像这样:
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,这样所有这些工具都更容易解释