Пользовательский элемент управления как контейнер во время проектирования

Я разрабатываю простое управление расширителем.

Я произошел из UserControl, оттянутые внутренние средства управления, созданные, работали; все хорошо.

Так как внутренним Управлением является Панель, я хотел бы использовать его в качестве контейнера во время проектирования. Действительно я использовал атрибуты:

[Designer(typeof(ExpanderControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 

Большой я говорю. Но это не...

Результат состоит в том, что я могу использовать его в качестве контейнера во время проектирования, но:

  • Добавленные средства управления возвращаются внутренние средства управления, уже встроенные в пользовательский элемент управления
  • Даже если я продвигаю для положения во главе управления, добавленного во время проектирования во времени выполнения, оно вернулось снова на средствах управления, встроенных в пользовательский элемент управления
  • Я не могу ограничить контейнерную область во время проектирования в область Panel

Что я пропускаю? Вот код для полноты..., почему этот отрывок кода не работает?

[Designer(typeof(ExpanderControlDesigner))]
[Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))] 
public partial class ExpanderControl : UserControl
{
    public ExpanderControl()
    {
        InitializeComponent();
....

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
internal class ExpanderControlDesigner : ControlDesigner
{
    private ExpanderControl MyControl;

    public override void Initialize(IComponent component)
    {
        base.Initialize(component);

        MyControl = (ExpanderControl)component;

        // Hook up events
        ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));
        IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));

        s.SelectionChanged += new EventHandler(OnSelectionChanged);
        c.ComponentRemoving += new ComponentEventHandler(OnComponentRemoving);
    }

    private void OnSelectionChanged(object sender, System.EventArgs e)
    {

    }

    private void OnComponentRemoving(object sender, ComponentEventArgs e)
    {

    }

    protected override void Dispose(bool disposing)
    {
        ISelectionService s = (ISelectionService)GetService(typeof(ISelectionService));
        IComponentChangeService c = (IComponentChangeService)GetService(typeof(IComponentChangeService));

        // Unhook events
        s.SelectionChanged -= new EventHandler(OnSelectionChanged);
        c.ComponentRemoving -= new ComponentEventHandler(OnComponentRemoving);

        base.Dispose(disposing);
    }

    public override System.ComponentModel.Design.DesignerVerbCollection Verbs
    {
        get
        {
            DesignerVerbCollection v = new DesignerVerbCollection();

            v.Add(new DesignerVerb("&asd", new EventHandler(null)));

            return v;
        }
    }
}

Я нашел много ресурсов (Взаимодействие, разработанное, ограниченная область), но ничто не было полезно для того, чтобы быть оператором...

На самом деле существует прием, начиная с Системы. Windows. Классы форм могут быть разработаны (как обычно), и иметь корректное поведение во времени выполнения (TabControl, например).

17
задан Community 23 May 2017 в 12:16
поделиться

1 ответ

ParentControlDesigner не знает, что вы хотите сделать. Он знает только, что вы хотите, чтобы ваш UserControl был контейнером.

Что вам нужно сделать, так это реализовать собственный дизайнер, который включает режим дизайна на панели:

    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;

    namespace MyCtrlLib
    {
        // specify my custom designer
        [Designer(typeof(MyCtrlLib.UserControlDesigner))]
        public partial class UserControl1 : UserControl
        {
            public UserControl1()
            {
                InitializeComponent();
            }

            // define a property called "DropZone"
            [Category("Appearance")]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
            public Panel DropZone
            {
                get { return panel1; }
            }
        }

        // my designer
        public class UserControlDesigner  : ParentControlDesigner
        {
            public override void Initialize(System.ComponentModel.IComponent component)
            {
                base.Initialize(component);

                if (this.Control is UserControl1)
                {
                    this.EnableDesignMode(
                       (UserControl1)this.Control).DropZone, "DropZone");
                }
            }
        }
    }

Я узнал об этом от Генри Минут на CodeProject. См. Ссылку для некоторых улучшений техники.

17
ответ дан 30 November 2019 в 13:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: