简体   繁体   English

WinForms-UserControl-列表 <bool> 集合 <bool> 作为UserControl的可浏览属性

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM