Arrays 将ComboBox/NumericUpDown选择绑定到数组?
我正在做一个VB项目,它有很多组合框和数字上下项 假设我们有ComboBox1、2、3、4和5;我们有数字上下1,2,3,4,5 当用户单击“保存”按钮时,我想将他们选择的所有组合框项目和numericupdown数字保存到CSV文件中。是否有一种优雅/自动的方法将这些项目的所有.SelectedIndex和.Value绑定到一个数组,以便我可以轻松地将数组写入CSV 到目前为止,我知道的唯一方法是手动将每个阵列与阵列位置关联:Arrays 将ComboBox/NumericUpDown选择绑定到数组?,arrays,vb.net,combobox,Arrays,Vb.net,Combobox,我正在做一个VB项目,它有很多组合框和数字上下项 假设我们有ComboBox1、2、3、4和5;我们有数字上下1,2,3,4,5 当用户单击“保存”按钮时,我想将他们选择的所有组合框项目和numericupdown数字保存到CSV文件中。是否有一种优雅/自动的方法将这些项目的所有.SelectedIndex和.Value绑定到一个数组,以便我可以轻松地将数组写入CSV 到目前为止,我知道的唯一方法是手动将每个阵列与阵列位置关联: Arr(0) = ComboBox1.SelectedIndex
Arr(0) = ComboBox1.SelectedIndex
Arr(1) = ComboBox2.SelectedIndex
...
Arr(5) = NumericUpDown1.Value
Arr(6) = NumericUpDown2.Value
...
etc.
这不会太糟糕,除非我有很多这样的项目,而且为每个项目写一行似乎很愚蠢。我是VB新手,所以这对某些人来说可能是一个显而易见的解决方案。有什么想法吗
将它们绑定到一个数组将非常方便,因为我还允许用户加载CSV文件,我希望从CSV值自动填充组合框和数字上下。我知道的唯一方法是在单击“加载文件”按钮时手动将每个数组项移动到相应的组合框/数字项:
ComboBox1.SelectedIndex = Arr(0)
ComboBox2.SelectedIndex = Arr(1)
...
NumericUpDown1.Value = Arr(5)
NumericUpDown2.Value = Arr(6)
...
etc.
编辑:这里是一些申请信息要求
可以保存/加载的CSV文件如下所示:
#"Device Info","123456","asdfgh","0000","1.0x","1"
000F,0000,0032,0000,00C8,0001,0078,0101,0000,0001,0000,0001
010F,0078,0000,0103,0001,0000,000A,0005,0007,0006,0000
0001,000A,000A,000A,000A,0005,0005,0005,0002
...etc
标题行只有序列号、版本和其他杂项信息;它由目标设备自动生成。所有其他行都是目标设备读入并自动配置自身的配置设定点。我写这个PC程序是为了能够用一个漂亮的GUI界面从零开始编辑和创建这些配置CSV文件。每个项目都与一个特定的设定点相关联,例如000F=语言、0032=系统频率、00C8=系统电压等。我看到制作此配置程序的最简单方法是使用数字输入和下拉组合框,用户可以选择他们想要的。每个NUD和CBOX都相当于一个CSV文件数据字段。您可以使用控件。查找可根据索引值获取所需控件的引用。这里有一个简单的例子来说明我的意思:
For i As Integer = 1 To 30
Dim matches() As Control = Me.Controls.Find("NumericUpDown" & i, True)
If matches.Length > 0 AndAlso TypeOf matches(0) Is NumericUpDown Then
DirectCast(matches(0), NumericUpDown).Value = i
End If
Next
您可以将这样的代码合并到加载/保存例程中。我将使用二进制序列化。这样在保存控件属性时就不需要格式化字符串或xml。与钚的解决方案类似,它仅适用于某些类型的控制。但是,它可以修改为适用于任何类型的控件,但只支持为每个控件加载单个属性。它将在所有类型为X的控件上工作,而不是在名为xName的控件上工作。通过在面板或其他方式中对要序列化的控件进行分组,可以添加更多限制 创建一个名为Form1的新表单。添加一些数字下拉列表、文本框和组合框。在设计时将一些值放入组合框中,否则在表单\ Load中调用loadState将毫无意义。但是,只要组合框已填充,就可以调用loadState 您将需要导入这两个名称空间:
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
在你们班:
Private Shared stateFileName As String = "SavedState.bin"
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
saveState(Me)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
loadState(Me)
End Sub
这些是您将用来保存和加载状态的方法。保存状态方法:
Private Shared Sub saveState(instance As Form)
Dim controlProperties As Dictionary(Of String, Object) =
instance.Controls.OfType(Of Control).ToDictionary(Of String, Object)(
Function(c) c.Name,
Function(c)
' You can support different types of controls here too
If TypeOf c Is NumericUpDown Then
Return CType(c, NumericUpDown).Value
ElseIf TypeOf c Is ComboBox Then
Return CType(c, ComboBox).SelectedIndex
Else
' All other controls get their text property saved
' .Text is a property of Control
Return c.Text
End If
End Function)
Using myFileStream As Stream = File.Create(stateFileName)
Dim serializer As New BinaryFormatter
serializer.Serialize(myFileStream, controlProperties)
End Using
End Sub
Private Shared Sub loadState(instance As Form)
If File.Exists(stateFileName) Then
Using myFileStream As Stream = File.OpenRead(stateFileName)
Dim deserializer As New BinaryFormatter()
Dim controlProperties = CType(deserializer.Deserialize(myFileStream), Dictionary(Of String, Object))
For Each c As Control In instance.Controls
If controlProperties.ContainsKey(c.Name) Then
' You can support different types of controls here too
If TypeOf c Is NumericUpDown Then
CType(c, NumericUpDown).Value = CDec(controlProperties(c.Name))
ElseIf TypeOf c Is ComboBox Then
CType(c, ComboBox).SelectedIndex = CInt(controlProperties(c.Name))
Else
c.Text = controlProperties(c.Name).ToString()
End If
End If
Next
End Using
End If
End Sub
负载状态方法:
Private Shared Sub saveState(instance As Form)
Dim controlProperties As Dictionary(Of String, Object) =
instance.Controls.OfType(Of Control).ToDictionary(Of String, Object)(
Function(c) c.Name,
Function(c)
' You can support different types of controls here too
If TypeOf c Is NumericUpDown Then
Return CType(c, NumericUpDown).Value
ElseIf TypeOf c Is ComboBox Then
Return CType(c, ComboBox).SelectedIndex
Else
' All other controls get their text property saved
' .Text is a property of Control
Return c.Text
End If
End Function)
Using myFileStream As Stream = File.Create(stateFileName)
Dim serializer As New BinaryFormatter
serializer.Serialize(myFileStream, controlProperties)
End Using
End Sub
Private Shared Sub loadState(instance As Form)
If File.Exists(stateFileName) Then
Using myFileStream As Stream = File.OpenRead(stateFileName)
Dim deserializer As New BinaryFormatter()
Dim controlProperties = CType(deserializer.Deserialize(myFileStream), Dictionary(Of String, Object))
For Each c As Control In instance.Controls
If controlProperties.ContainsKey(c.Name) Then
' You can support different types of controls here too
If TypeOf c Is NumericUpDown Then
CType(c, NumericUpDown).Value = CDec(controlProperties(c.Name))
ElseIf TypeOf c Is ComboBox Then
CType(c, ComboBox).SelectedIndex = CInt(controlProperties(c.Name))
Else
c.Text = controlProperties(c.Name).ToString()
End If
End If
Next
End Using
End If
End Sub
您应该添加异常处理,并注意,没有机器的帮助,二进制文件不能由人工编辑。数组只是一个中介。没有理由说数据不能直接从控件传递到文件,反之亦然。@如果使用数组,我可以轻松地遍历数组以输出到CSV,对吗?但是,如果有一堆ComboBox.SelectedIndex,您将如何索引以输出到CSV?streamwriter.WriteList{0}、{1}、cbo1.SelectedIndex.ToString、nud1.Value.ToString因此,是的,您没有在循环中使用它的索引,但也不会让索引将值放入数组中-这只是额外的一步。此外,保存索引意味着cbo将始终具有相同的内容。错误的假设。最好保存文本值。嗯,我不熟悉WriteList。有关于这方面的教程或示例吗?我知道这可能是个问题。我的组合框项目是硬定义的,将来除了在项目列表的末尾添加一个新项目外,永远不会更改,因此我认为在我的情况下这样做是可以的。很好的建议,如果用户可以编辑这些项目。对不起,应该是书面的。这很有趣。这超出了我目前对VB的理解,但我会看一看。随着更多细节在评论中慢慢流出,字典将无法工作,其他东西正在创建文件,如果该东西也重新读取更新的值,那么它可能需要保持CSV。很难说这一切都太抽象和模糊了。@啊,我不太清楚。这个问题现在有点道理了。很高兴看到一个所需csv的示例。。。哦,好吧,也许其他人可以使用这个方法来序列化他们的表单。如果知道什么是逻辑的东西就好了
也表示-由CBO+NUD组成的用户控件可能会工作。这是一个越来越令人遗憾的问题,因为我太含糊不清了。我在这篇文章中添加了更多的信息。这些东西对我来说是非常新的,因此我不知道我需要在原来的文章中包含什么。