我有一个Panel,我希望在运行时填充一些UserControl。这些控件很复杂,可能是相互依赖的,所以我喜欢它们:
这两项要求都是必须的。
考虑到UserControl本身就是一个Control(s)的索引集合,我开始在同一个类中设计我的控件,而不关心它们的真实定位(将指定运行时)。我已经使用与DevComponents带状容器相同的相同方法(非常满意),所以我最初认为使用标准UserControl可以实现相同的目的。
我最终意识到Control一次只能在一个Control.ControlCollection实例中,所以我无法使用Controls属性并将控件添加到另一个面板而不从原始的“虚拟”UserControl中删除它们。
我的问题是:是否有一种干净且受支持的方式来创建这个设计师感知的UserControl集合?我会称这种方法为一种模式,因为它确实增加了代码的清晰度和效率。
谢谢, 弗朗西斯
P.S。:作为一种解决方法,我创建了一个DummyControlContainer类,它继承UserControl并保持在ControlAdded事件中填充的Dictionary映射(代码如下)。想知道是否有更清洁的东西。
public partial class DummyControlContainer : UserControl
{
private Dictionary<string, Control> _ControlMap;
public DummyControlContainer()
{
InitializeComponent();
_ControlMap = new Dictionary<string, Control>();
this.ControlAdded += new ControlEventHandler(DummyControlCollection_ControlAdded);
}
void DummyControlCollection_ControlAdded(object sender, ControlEventArgs args)
{
_ControlMap.Add(args.Control.Name, args.Control);
}
public Control this[string name]
{
get { return _ControlMap[name]; }
}
}
答案 0 :(得分:0)
在现实世界的项目中测试并使用它后,我越来越相信如果你需要这样的模式,我的解决方案是干净和安全的。该容器旨在填充诸如面板或类似物的控件。为了防止使用可绑定数据源的某些不良行为,我将每个新控件添加到此容器中,并使用自己的BindingContext。享受。
public partial class DummyControlContainer : UserControl
{
private Dictionary<string, Control> _ControlMap;
public DummyControlContainer()
{
InitializeComponent();
_ControlMap = new Dictionary<string, Control>();
this.ControlAdded +=
new ControlEventHandler(DummyControlCollection_ControlAdded);
}
void DummyControlCollection_ControlAdded(object sender,
ControlEventArgs args)
{
// If the added Control doesn't provide its own BindingContext,
// set a new one
if (args.Control.BindingContext == this.BindingContext)
args.Control.BindingContext = new BindingContext();
_ControlMap.Add(args.Control.Name, args.Control);
}
public Control this[string name]
{
get { return _ControlMap[name]; }
}
}