から継承するユーザー コントロールを作成しました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 で何をしているのかわからないことがわかります... ;)