我正在开发一个项目,该项目要求用户为其客户创建未指定数量的捕获字段。在这样做时,我想创建一个通用模板,其中他们键入新字段的名称,并从组合框中选择一个类型。组合框的值('自由文本'布尔','十进制'等)可以存储在任何地方(即我不挑剔)关于他们如何约束)。 selectedIndexChanged事件将处理相应的usercontrol的添加。但是,由于我不知道我将处理多少值类型(现在看起来像7-9),我想避免使用以下类型的代码:
Private Sub cbxType_SelectedIndexChanged(sender As Object, e As EventArgs)
If cbxType.SelectedItem = "Free Text" Then
Dim vText As VTText = New VTText() ' This is the usercontrol for text
Controls.Add(vText)
ElseIf cbxType.SelectedItem = "Boolean" Then
Dim vBool As VTBool = New VTBool() ' etc.
...
我的第一个想法是在表单加载
时使用某种键值对的列表/字典Dim kList As List(Of KeyValuePair(Of String, Object)) = New List(Of KeyValuePair(Of String, Object))
kList.Add(New KeyValuePair(Of String, Object)("Text", New vText())
For each kpair As KeyValuePair(Of String, Object) In kList
cbx.Items.Add(kPair.Key)
Next
在更改事件处理程序中使用类似的东西
Dim myControl = DirectCast(cbxType.SelectedItem, KeyValuePair(Of String, Object)).Value
Controls.Add(myControl)
但是,selectedvalue属性为空,我得到一个无效的强制转换异常。我试过转换为Control和UserControl,但那些当然没有用。 这种做法,除非我的错误实施,听起来不错?有一个更好的方法吗?理想情况下,我想要一条有效地执行此类操作的行:
Controls.Add(cbxType.SelectedValue)
答案 0 :(得分:1)
您可以创建一个类来保存控件以及显示文本,并将这些对象绑定为组合框的数据源。然后,您就可以实现一个衬垫,以便为您的收藏添加控件。
示例(假设我有一个带有组合框(Combobox1)和一个Button(Button1)的表单:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If (Not ComboBox1.SelectedItem Is Nothing) Then
GroupBox1.Controls.Add(Activator.CreateInstance(ComboBox1.SelectedItem.ControlType))
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'add some controls to the cbx
Dim ctrl As New MyControl
ctrl.DisplayText = "TextBox"
ctrl.ControlType = GetType(System.Windows.Forms.TextBox)
Me.ComboBox1.Items.Add(ctrl)
End Sub
End Class
Public Class MyControl 'The thing that i have also done is add the Display Memeber and Value Member on my Combobox.
Public DisplayText As String
Public ControlType As Type
End Class
答案 1 :(得分:1)
这是另一个类似于DotNetHitMan之前建议的选项......
首先,在UserControls中覆盖 ToString(),以设置它们在ComboBox中的显示方式。例如:
Public Class VTText
' ... other code in your UserControl ...
Public Overrides Function ToString() As String
Return "Free Text"
End Function
' ... other code in your UserControl ...
End Class
Public Class VTBool
' ... other code in your UserControl ...
Public Overrides Function ToString() As String
Return "Boolean"
End Function
' ... other code in your UserControl ...
End Class
接下来,将ComboBox的 FormattingEnabled 设置为False,并在Form的Load()事件中将UserControl的实例直接添加到ComboBox:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ComboBox1.FormattingEnabled = False
ComboBox1.Items.Add(New VTText)
ComboBox1.Items.Add(New VTBool)
' ... etc ... (one entry per type of your UserControls)
End Sub
现在添加一个模块,以便为Control创建扩展方法,允许您根据传入的Control类型创建一个新实例:
Public Module Extensions
<Runtime.CompilerServices.Extension()>
Public Function GetNewInstance(ByVal ctl As Control) As Control
Return Activator.CreateInstance(ctl.GetType)
End Function
End Module
最后,在Button click处理程序中,将ComboBox.SelectedItem强制转换为Control并调用 GetNewInstance()扩展函数:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ComboBox1.SelectedIndex <> -1 Then
Dim ctl As Control = DirectCast(ComboBox1.SelectedItem, Control).GetNewInstance
' ... do other stuff with "ctl" ? ...
FlowLayoutPanel1.Controls.Add(ctl)
End If
End Sub