在Designer支持下将表单作为属性添加到用户控件 [英] Adding a Form as a property to a user control with Designer support
问题描述
我已经创建了一个自定义标签.它具有 Form
类型的属性,用户可以在设计器中选择该表单,然后单击标签时将加载该表单.它可以正常工作,但属性下拉列表中的唯一形式是标签所在的形式.
是否可以显示所有可能的表单,或者让用户将表单作为字符串传递,然后将其转换为表单?
这是我标签的代码:
公共类BMLabel私有t作为字符串私有ID作为字符串私人frm作为新形式<类别("BM")>公共属性类型为字符串得到返回t结束获取设置(值作为字符串)t =值端套最终财产公共属性标识符为字符串得到返回编号结束获取设置(值作为字符串)id =值端套最终财产公共财产表格得到返回frm结束获取设置(值形式)frm =值端套最终财产私有Sub BMLabel_Click(作为对象发送,作为EventArgs发送)处理我.昏暗t = frm.GetType()昏暗的形式为Form = DirectCast(Activator.CreateInstance(t),Form)form.ShowDialog()结束子末级
问题是,当您声明类型为 Form
的属性时,它允许您选择 form实例,而不是继承自 Form
的类型/类.您需要做的是声明一个类型为 Type
的属性,并准备编辑器,该编辑器将允许您选择所需的类型(将选项限制为从 Form
).
免责声明:创建自定义编辑器的想法是受
公共类FormTypeSelector朋友属性值作为类型私有子FormTypeSelector_Load(发送者作为对象,e作为EventArgs)处理MyBase.Load昏暗的availableFormTypes =System.Reflection.Assembly.GetExecutingAssembly().GetTypes().其中(Function(t)t.BaseType = GetType(Form)And t Me.GetType()).ToList()cboFormTypes.DisplayMember =名称"cboFormTypes.DataSource = availableFormTypescboFormTypes.SelectedItem =值结束子Private Sub BtnOK_Click(发送者为对象,e作为EventArgs)处理btnOK.Click值= DirectCast(cboFormTypes.SelectedItem,类型)DialogResult = DialogResult.OK关闭()结束子私有Sub btnCancel_Click(发送者为对象,e作为EventArgs)处理btnCancel.ClickDialogResult = DialogResult.Cancel关闭()结束子末级
就是这样;它应该准备好了:
注意:您可能需要在
FormTypeSelector
中添加一个选项,以允许清除FormType
属性的选定值,这应该很容易做到.>I have created a custom label. It has a property of type
Form
, which the user can select the form in the designer and then when the label is clicked that form is loaded. It works fine but the only form in the properties dropdown list is the one that the label is on.Is there a way to show all possible forms or perhaps have the user pass the form as a string and then convert that to be a form.
Here is the code for my label:
Public Class BMLabel Private t As String Private id As String Private frm As New Form <Category("BM")> Public Property Type As String Get Return t End Get Set(value As String) t = value End Set End Property Public Property Identifier As String Get Return id End Get Set(value As String) id = value End Set End Property Public Property Form As Form Get Return frm End Get Set(value As Form) frm = value End Set End Property Private Sub BMLabel_Click(sender As Object, e As EventArgs) Handles Me.Click Dim t = frm.GetType() Dim form As Form = DirectCast(Activator.CreateInstance(t), Form) form.ShowDialog() End Sub End Class
解决方案The problem is that when you declare a property of type
Form
, it allows you to select a form instance, not a type/class that inherits fromForm
. What you need to do instead is declare a property of typeType
and prepare the editor which will allow you to select the desired type (limiting the options to the types that inherit fromForm
).Disclaimer: The idea of creating a custom editor was inspired by this answer and the code was adapted for this particular situation.
So, here we go. The custom label class would look something like this:
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
Now, we need to create the
TypeSelector
class: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
Then, we create a form called
FormTypeSelector
with aComboBox
or aListBox
to list the available options: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
And that's it; it should be ready to go:
Note: You'll probably need to add an option in
FormTypeSelector
to allow clearing the selected value of theFormType
property which should be easy enough to do.这篇关于在Designer支持下将表单作为属性添加到用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!