c# - UserControl 在设计时生成子控件
问题描述
我正在尝试在 Windows 窗体中创建一个用户控件,它将具有“生成”子控件的功能。例子:
假设我们有只有flowlayoutpanel
, 和 ButtonText
属性的 UC:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public List<ButtonBlueprint> ButtonText { get; set; } = new List<ButtonBlueprint>();
ButtonBlueprint
只是字符串的包装器,没关系:
public class ButtonBlueprint
{
public string Name { get; set; }
}
我想要但我不知道如何实现的是从这个集合中的项目生成按钮。进入运行时很容易:
但我希望在设计时生成这些控件并在设计器中可见。这可能吗?我知道一些高级控件,例如来自 Telerik 的控件具有类似的功能,并且可以从类模式生成控件,所以它应该是可能的。关于如何做到这一点的任何建议?
解决方案
好吧,您不仅需要在设计时生成子控件,还需要通过将它们序列化为 *.Designer.cs 来保持更改。如果我很好地理解了您的问题,您可以从以下代码中获得启发。只是一个非常简单的示例(仅通过向 *.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);
}
}
}
推荐阅读
- asp.net-core - 有没有办法为同一个控制器使用两种身份验证方案?
- html - 检测布尔值是否更改Angular 8
- emacs - Emacs lisp,如何在 IELM 中换行?
- r - 从数据框中填充矩阵
- netcdf - 在单个命令中将两个 NetCDF 文件中的变量相乘
- python - 系统错误:
返回 NULL 而不设置错误 - python-3.x - 远程服务器上的 PyCharm 不显示未使用的导入、#fixme 等
- node.js - 在 nodejs 中每分钟调用 5 个 API
- gradle - 初始化数据库时的 Gradle 任务
- android - 如何删除此 Xamarin 网格布局顶部的空间?