2

Я пытаюсь добавить поддержку дизайнера для моего настраиваемого элемента управления WinForms, но он выглядит только активным, когда у меня уже есть экземпляр, а не во время drag'n'drop из Toolbox.ControlDesigner не активен при перетаскивании элемента управления с панели инструментов

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

[Designer(typeof(MyButtonDesigner))] 
public class MyButton:Button 
{ 
    public MyButton() 
    { 
     base.Size= new Size(50,50); 
    } 
} 
class MyButtonDesigner : ControlDesigner 
{ 
    public override bool CanBeParentedTo(IDesigner parentDesigner) 
    { 
     return parentDesigner != null && parentDesigner.Component is Form; 
    } 
} 

Я хочу, чтобы мой контроль, чтобы путь прошел только по форме (пользователь будет иметь возможность добавлять контроль только к форме, не к групповому ящику). Когда я перетащить управления из панели инструментов моя логика проверки будет пропущена, но когда я пытаюсь переместить мой экземпляр управления от формы к Groupbox я могу видеть, что падение проверяется (как показано ниже)

enter image description here

Я довольно новый для ControlDesigner, поэтому я не уверен, является ли это поведение по дизайну или я могу изменить его, чтобы моя проверка выполнялась при перетаскивании с панели инструментов.

Я использую Visual Studio 2013, но я не думаю, что это должно быть проблемой.

ответ

2

CanBeParentedTo Метод не вызывается, когда элемент перетаскивается из панели инструментов на поверхность дизайна.
Вы можете создать пользовательский ToolBoxItem для вашего управления, а затем переопределить метод CreateComponentsCore, чтобы предотвратить создание элемента управления, если родительский элемент не является Form. ToolBoxItem будет использоваться, когда управление перетаскиванием из ToolBox и Designer будет использоваться при перетаскивании управления с поверхности дизайна.

//Add reference to System.Drawing.dll then using 
using System.Drawing.Design; 
using System.Windows.Forms.Design; 
public class MyButtonToolBoxItem:ToolboxItem 
{ 
    protected override IComponent[] CreateComponentsCore(IDesignerHost host, 
     System.Collections.IDictionary defaultValues) 
    { 
     if(defaultValues.Contains("Parent")) 
     { 
      var parent = defaultValues["Parent"] as Control; 
      if(parent!=null && parent is Form) 
       return base.CreateComponentsCore(host, defaultValues); 
     } 

     var svc = (IUIService)host.GetService(typeof(IUIService)); 
     if (svc != null) svc.ShowError("Can not host MyButton in this control"); 

     return null; 
    } 
} 

Чтобы зарегистрировать элемент панели инструментов для управления:

[ToolboxItem(typeof(MyButtonToolBoxItem))] 
[Designer(typeof(MyButtonDesigner))] 
public class MyButton : Button 

В результате, когда вы перетащите элемент управления из панели инструментов и поместите его в любой емкости, кроме формы, он показывает сообщение пользователя и ничего не происходит, и он не будет добавлен к этому родителю. Если хотите, вы можете удалить сообщение.

+0

Большое вам спасибо, я никогда не использовал класс ToolboxItem, о чем я должен прочитать. Все работает отлично, кроме одного. Когда я перетаскиваю элемент из панели инструментов в нечто другое, кроме формы, он не добавляется (как и ожидалось), но курсор мыши все еще указывает, что я могу его туда отбросить. Могу ли я поменять курсор на «Нет», потому что теперь он немного запутан - пользователь видит, что он может сбросить контроль, но на самом деле я его предотвращаю. – Misiu

+0

Добро пожаловать, в настоящее время в качестве решения, я решил показать ошибку Visual Studio. Я применил редактирование для публикации. –

+0

Другим обходным решением является 'if (host.RootComponent is Form) defaultValues ​​[" Parent "] = host.RootComponent;' он изменяет целевую точку кавычки как 'Form'. Я предпочитаю показывать сообщение об ошибке. –