Reputation: 1897
I'm trying to create a user control in Windows Forms, with will have the function of "generating" subcontrols. Example:
Let say that we have UC with only flowlayoutpanel
, and ButtonText
property:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<ButtonBlueprint> ButtonText { get; set; } = new List<ButtonBlueprint>();
ButtonBlueprint
is just wrapper for string, doesn't matter:
public class ButtonBlueprint
{
public string Name { get; set; }
}
Now, I got a nice editor in designer for this collection:
What I want and I don't know how to achieve is to generate buttons from items in this collection. It's easy when you kick in into runtime:
But i want to have those controls generated and being visible in designer while being during design-time. Is this possible? I know that some advanced controls, for example from Telerik has a similar feature and can generated controls from a class schema, so it should be possible. Any advice on how to do this?
Upvotes: 0
Views: 187
Reputation: 180
Well, you need not only generating the subcontrols during designtime, but you also need to keep the changes by serializing them to *.Designer.cs.. If I understood your problem well, you can get inspired by following piece of code. Just a very simple sample (persistency done only by adding a comment to the *.Designer.cs).
using System;
using System.CodeDom;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Windows.Forms;
using ControlDesigner = System.Windows.Forms.Design.ControlDesigner;
namespace WindowsFormsApp1
{
[DesignerSerializer(typeof(TestSerializer), typeof(CodeDomSerializer))]
[Designer(typeof(TestEditor), typeof(IDesigner))]
public partial class TestControl1 : UserControl
{
public TestControl1()
{
InitializeComponent();
}
}
public class TestEditor : ControlDesigner
{
private static int _counter;
public TestEditor()
{
Verbs.Add(new DesignerVerb("Add button", Handler));
}
private void Handler(object sender, EventArgs e)
{
var button = new Button
{
Enabled = true,
Text = "Hello",
Name = string.Format("Button{0}", ++_counter)
};
button.Location = new Point(0, _counter * button.Size.Height);
((TestControl1)Component).Controls.Add(button);
}
}
public class TestSerializer : CodeDomSerializer
{
public override object Serialize(IDesignerSerializationManager manager, object value)
{
if (value.GetType() == typeof(TestControl1))
{
var serializer = manager.GetSerializer(typeof(TestControl1).BaseType, typeof(CodeDomSerializer)) as CodeDomSerializer;
if (serializer != null)
{
var coll = serializer.Serialize(manager, value) as CodeStatementCollection;
if (coll != null)
{
var tc = (TestControl1)value;
foreach (Control control in tc.Controls)
{
coll.Insert(0, new CodeCommentStatement("Component " + control.Name));
}
}
return coll;
}
}
return base.Serialize(manager, value);
}
}
}
Upvotes: 1