Проблема в том, что когда вы объявляете свойство типа Form
, оно позволяет вам выбрать экземпляр формы , а не тип / класс, который наследуется от Form
,Вместо этого вам нужно объявить свойство типа Type
и подготовить редактор, который позволит вам выбрать нужный тип (ограничивая параметры типами, которые наследуются от Form
).
Отказ от ответственности: Идея создания пользовательского редактора была вдохновлена этим ответом , и код был адаптирован для этой конкретной ситуации.
Итак, поехали. Пользовательский класс метки будет выглядеть примерно так:
Public Class BMLabel
Inherits Label
' Don't forget to change the namespace.
' ↓↓↓↓↓↓↓↓↓↓↓
<Editor("WindowsApp1.TypeSelector, System.Design", GetType(UITypeEditor)), Localizable(True)>
Public Property FormType As Type
Private Sub BMLabel_Click(sender As Object, e As EventArgs) Handles Me.Click
Using frm As Form = DirectCast(Activator.CreateInstance(FormType), Form)
frm.ShowDialog(Me)
End Using
End Sub
End Class
Теперь нам нужно создать класс TypeSelector
:
Public Class TypeSelector
Inherits UITypeEditor
Public Overrides Function GetEditStyle(context As ITypeDescriptorContext) As UITypeEditorEditStyle
If context Is Nothing OrElse context.Instance Is Nothing Then
Return MyBase.GetEditStyle(context)
End If
Return UITypeEditorEditStyle.Modal
End Function
Public Overrides Function EditValue(context As ITypeDescriptorContext, provider As IServiceProvider, value As Object) As Object
Dim editorService As IWindowsFormsEditorService
If context Is Nothing OrElse context.Instance Is Nothing OrElse provider Is Nothing Then
Return value
End If
editorService = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)),
IWindowsFormsEditorService)
Dim dlg As New FormTypeSelector()
dlg.Value = DirectCast(value, Type)
dlg.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
If editorService.ShowDialog(dlg) = System.Windows.Forms.DialogResult.OK Then
Return dlg.Value
End If
Return value
End Function
End Class
Затем мы создадим форму с именем FormTypeSelector
с помощью ComboBox
или ListBox
для просмотра списка доступных опций:
Public Class FormTypeSelector
Friend Property Value As Type
Private Sub FormTypeSelector_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim availableFormTypes =
System.Reflection.Assembly.GetExecutingAssembly().
GetTypes().
Where(Function(t) t.BaseType = GetType(Form) AndAlso t <> Me.GetType()).ToList()
cboFormTypes.DisplayMember = "Name"
cboFormTypes.DataSource = availableFormTypes
cboFormTypes.SelectedItem = Value
End Sub
Private Sub BtnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
Value = DirectCast(cboFormTypes.SelectedItem, Type)
DialogResult = DialogResult.OK
Close()
End Sub
Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
DialogResult = DialogResult.Cancel
Close()
End Sub
End Class
И это все;он должен быть готов к работе:
Примечание: вам, вероятно, потребуется добавить параметр в FormTypeSelector
, чтобы разрешить очистку выбранного значениясвойство FormType
, которое должно быть достаточно простым.