我创建了一个继承自Panel
. 目标是拥有一组可折叠面板。
这是我的用户控件的样子(对丑陋的没有评论:P)
我正在使用一个主类作为控件,另一个用于集合(使用CollectionBase
)和第三个,即 item。
我的问题是当我添加一个项目时,我需要主控件来添加另一个面板。目前绘图看起来不错,但我没有得到预期的结果。
我不确定我是否清楚地暴露了我的问题。假设在 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 的第二个类如下:
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;
}
}
第三类,集合的项目:
[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 类时,您会明白我不知道我的面板在做什么...... ;)