Иногда вам может понадобиться сгенерировать некоторый код при удалении компонента в форму. Например, вы можете увидеть похожее поведение, когда перетаскиваете источник данных из окна источника данных и помещаете его в форму.
Поведение более распространено для расширений и надстроек, но вы можете реализовать такое поведение и для своего компонента при удалении из панели инструментов.
Ключевые моменты в ответе:
- Создание нового конструктора для элемента управления путем вывода из
ControlDesigner
- Создание обработчика событий с использованием
IEventBindingService
- Добавление кода в тело обработчика событий с использованием службы
CodeTypeDeclaration
.
Пример
Я создал MyControl
элемент управления в этом примере. Когда вы удаляете экземпляр элемента управления на форме, конструктор сгенерирует следующий код для своего события Click
:
private void myControl1_Click(object sender, EventArgs e)
{
MessageBox.Show("Hi!");
}
Вот код MyControl
и MyControlDesigner
. Возможно, вы захотите добавить нулевую проверку к коду.
using System.CodeDom;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.Design;
[Designer(typeof(MyControlDesigner))]
public partial class MyControl : Control
{
}
public class MyControlDesigner : ControlDesigner
{
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
var component = this.Component;
var eventBindingService = (IEventBindingService)this.GetService(
typeof(IEventBindingService));
var componentChangeService = (IComponentChangeService)this.GetService(
typeof(IComponentChangeService));
var designerHostService = (IDesignerHost)GetService(typeof(IDesignerHost));
var uiService = (IUIService)GetService(typeof(IUIService));
var designerTransaction = (DesignerTransaction)null;
try
{
designerTransaction = designerHostService.CreateTransaction();
var e = TypeDescriptor.GetEvents(component)["Click"];
if (e != null)
{
var methodName = eventBindingService.CreateUniqueMethodName(component, e);
var eventProperty = eventBindingService.GetEventProperty(e);
if (eventProperty.GetValue(component) == null)
{
eventProperty.SetValue(component, methodName);
var code = this.GetService(typeof(CodeTypeDeclaration))
as CodeTypeDeclaration;
CodeMemberMethod method = null;
var member = code.Members.Cast<CodeTypeMember>()
.Where(x => x.Name == methodName).FirstOrDefault();
if (member != null)
{
method = (CodeMemberMethod)member;
method.Statements.Add(
new CodeSnippetStatement("MessageBox.Show(\"Hi!\");"));
}
componentChangeService.OnComponentChanged(component,
eventProperty, null, null);
eventBindingService.ShowCode(component, e);
}
}
designerTransaction.Commit();
}
catch (System.Exception ex)
{
if (designerTransaction != null)
designerTransaction.Cancel();
uiService.ShowError(ex);
}
}
}