0

から継承するユーザー コントロールを作成しましたPanel。目標は、折りたたみ可能なパネルのコレクションを持つことです。

これが私のユーザーコントロールの外観です(醜いコメントはありません:P) コントロールにメインクラスを使用し、コレクションに別のクラス(を使用CollectionBase)、およびアイテムである3番目のクラスを使用しています。

私の問題は、アイテムを追加するときです。別のパネルを追加するには、メイン コントロールが必要です。現在、図面は問題ないように見えますが、期待した結果が得られません。

自分の問題を明確に公開できるかどうかわかりません。Visual Studio で、Panel1 を Form1 に配置し、Panel2 + Panel 3 を Panel 1 に配置するとします。

含まれるForm1.Designer.csもの:

    Form1.Controls.Add(Panel1);
    Panel1.Controls.Add(Panel2); 
    Panel1.Controls.Add(Panel3);

これは私が喜んで行うものです。パネルを追加するためにイベントを作成してOnItemAddedサブスクライブしようとしましたが、魅力のように機能しませんでした。さらに、一度だけ実行する必要があるときにコレクションにデータが入力されるたびに、コンパイル時にトリガーされました。

英語が下手で申し訳ありません。何か明確にする必要がある場合は、遠慮なく教えてください。コードの一部が必要かどうかはわかりませんが、必要な場合はお問い合わせください。

事前にヒントをありがとう!

こんにちは terrybozzio さん、ご回答ありがとうございます。

ここにコードの重要な部分があります。ファーストクラス、メイン

    [Designer(typeof(CollapsiblePanelDesigner))]
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
    public partial class CollapsiblePanel : Panel
    {
        private CollapsiblePanelItemCollection _items = null;

        [Browsable(true)]
        [Editor(typeof(CollapsiblePanelItemCollectionEditor), typeof(UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public CollapsiblePanelItemCollection Items
        {
            get { return _items; }
        }

        public CollapsiblePanel()
        {
            InitializeComponent();
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint ControlStyles.OptimizedDoubleBuffer, true);
            _items = new CollapsiblePanelItemCollection(this);
        }

}

CollectionBase を継承する 2 番目のクラスは次のとおりです。

    public class CollapsiblePanelItemCollection : CollectionBase
    {
        private CollapsiblePanel _owner = null;

        public int IndexOf(CollapsiblePanelItem item)
        {
            return InnerList.IndexOf(item);
        }

        public CollapsiblePanelItem this[int index]
        {
            get { return (CollapsiblePanelItem)InnerList[index]; }
        }

        public CollapsiblePanelItemCollection(CollapsiblePanel owner)
        {
            _owner = owner;
        }

        public void Add(CollapsiblePanelItem item) { }

        public bool Remove(CollapsiblePanelItem item) { }

}

    public class CollapsiblePanelItemCollectionEditor : CollectionEditor
    {

        private Type[] _types;

        public CollapsiblePanelItemCollectionEditor(Type type) : base(type)
        {
            _types = new Type[] { typeof(CollapsiblePanelItem) };
        }

        protected override Type[] CreateNewItemTypes()
        {
            return _types;
        }
    }

3 番目のクラス、コレクションのアイテム:

    [DefaultProperty("Text")]
    [TypeConverter(typeof(CollapsiblePanelItemConverter))]
    public class CollapsiblePanelItem
    {
        private bool _isCollapsed = false;
        private string _text = "Text"; 
        private int _index = -1;
        private Panel _panel = new Panel();

        // simplified properties of course
        [DefaultValue(false)]
        public bool IsCollapsed { { get ; set; } }

        [DefaultValue(typeof(string), "Text")]
        public string Text { { get ; set; } }

        [Browsable(false)]
        public int Index { { get ; set; } }

        public Panel Panel { { get ; set; } }

        public CollapsiblePanelItem() { }

        public CollapsiblePanelItem(string Text, int ContainerSize, Image Image, bool IsCollapsed)
        {
            _text = Text;
            _containerHeight = ContainerHeight;
            _headerImage = Image;
            _isCollapsed = IsCollapsed;
        }
    }

    public class CollapsiblePanelItemConverter : ExpandableObjectConverter
    {

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return (destinationType == typeof(InstanceDescriptor)) ? true : base.CanConvertTo(context, destinationType);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(InstanceDescriptor))
            {
                if (value is CollapsiblePanelItem)
                {
                    CollapsiblePanelItem objValue = (CollapsiblePanelItem)value;
                    Type[] types = new Type[3];
                    object[] values = new object[3];
                    types[0] = typeof(Panel);
                    values[0] = objValue.Panel;
                    types[1] = typeof(string);
                    values[1] = objValue.Text;
                    types[2] = typeof(int);
                    values[2] = objValue.Index;
                    return new InstanceDescriptor(typeof(CollapsiblePanelItem).GetConstructor(types), values, true);
                }
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

もちろん、CollapsiblePanelItem クラスを読むと、Panel で何をしているのかわからないことがわかります... ;)

4

0 に答える 0