【问题标题】:Create a designer-aware UserControl collection to be used runtime创建要在运行时使用的设计器感知 UserControl 集合
【发布时间】:2010-09-15 16:14:00
【问题描述】:

我有一个面板,我想在运行时填充一些用户控件。这些控件很复杂,可能相互依赖,所以我想要它们:

  • 可使用 Visual Studio 设计器进行编辑;
  • 在同一上下文中(= 在同一类中定义);

这两个要求都是必须的。

考虑到 UserControl 本身是控件的索引集合,我开始在同一个类中设计我的控件,而不关心它们的实际定位(将指定运行时)。我已经对 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]; }
    }
}

【问题讨论】:

    标签: c# .net collections user-controls designer


    【解决方案1】:

    在实际项目中对其进行测试和使用后,我越来越相信如果您需要这样的模式,我的解决方案是干净且安全的。该容器旨在填充诸如面板或类似的控件。为了防止可绑定数据源出现一些不良行为,我为添加到此容器的每个新控件提供了自己的 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]; }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 1970-01-01
      • 2017-06-28
      • 2018-03-10
      相关资源
      最近更新 更多