几天来,我一直在寻找任何可能的参考或建议,但我遇到的一切都没有奏效。
目标:
用户将选择ComboBox1中的选项,然后确定ComboBox2中的可用选项,然后填充ListBox1中的操作列表。
当用户在ListBox1中选择可用的操作时,我需要输出将值(在本例中是以分钟为单位的总时间)的总和输入到标签中以供显示。
使用的数据存储在本地数据库中。到目前为止,我的组合框和列表框都可以正常工作。
我正在尝试获取ListBox1中所有选定项目的文本值,以输出表(第4列"OperationsTime")中的数值到一个标签中,该标签将显示所有选定项目的总和(以分钟为单位的总时间)。
我在其他文章中尝试过的一些东西::
文本标签9.Text= ListBox1.ValueMember
尝试使用双精度:
Dim Total As Double = 0
For Each Time As Integer In ListBox1.SelectedItems
Total += CDbl(Time.ToString.Substring(Time.ToString.LastIndexOf(",") + 1))
Next
Label9.Text = Total.ToString
表的屏幕截图: Operations Data Table
下面的是我的代码:
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Public Class MainHome
Private Function GetData(ByVal sql As String) As DataTable
Dim constr As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\hartj\Documents\visual studio 2015\Projects\TIMEMATRIX2.0\TIMEMATRIX2.0\TMX.mdf;Integrated Security=True"
Using con As SqlConnection = New SqlConnection(constr)
Using sda As SqlDataAdapter = New SqlDataAdapter(sql, con)
Dim dt As DataTable = New DataTable()
sda.Fill(dt)
Dim row As DataRow = dt.NewRow()
row(0) = 1
row(1) = "Please Select"
dt.Rows.InsertAt(row, 0)
Return dt
End Using
End Using
End Function
Private Sub MainHome_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
ComboBox1.DataSource = Me.GetData("SELECT SizeId, SizeName FROM Size")
ComboBox1.DisplayMember = "SizeName"
ComboBox1.ValueMember = "SizeId"
ComboBox2.Enabled = False
ComboBox3.Enabled = False
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox2.DataSource = Nothing
ComboBox3.DataSource = Nothing
ComboBox2.Enabled = False
ComboBox3.Enabled = False
If ComboBox1.SelectedValue.ToString() <> "0" Then
Dim sql As String = String.Format("SELECT DetailLevelId, DetailLevelName FROM DetailLevel WHERE SizeId = {0}", ComboBox1.SelectedValue)
ComboBox2.DataSource = Me.GetData(sql)
ComboBox2.DisplayMember = "DetailLevelName"
ComboBox2.ValueMember = "DetailLevelId"
ComboBox2.Enabled = True
End If
End Sub
Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
ListBox1.DataSource = Nothing
ListBox1.Enabled = False
If ComboBox2.SelectedValue.ToString() <> "0" Then
Dim sql As String = String.Format("SELECT OperationsId, OperationsName, OperationsTime FROM Operations WHERE DetailLevelId = {0}", ComboBox2.SelectedValue)
ListBox1.DataSource = Me.GetData(sql)
ListBox1.ValueMember = "OperationsName"
ListBox1.ValueMember = "OperationsTime"
ListBox1.Enabled = True
Label9.Text = CType(ListBox1.SelectedValue, Integer).ToString
'Label.Text = CType(cbbank.SelectedItem, DataRowView).Row.Item("Account").ToString
End IF
End Sub
发布于 2018-08-29 07:14:25
Dim totalOperationsTime As Double
For Each view As DataRowView In ListBox1.SelectedItems
totalOperationsTime += CDbl(view("OperationsTime"))
Next
不需要从DataRowView
获取DataRow
,因为您可以直接从DataRowView
访问字段值。它可以也确实可以做许多与DataRow
相同的事情。
这是最传统的方式,但也有其他选择。你可以使用一些LINQ:
Dim totalOperationsTime = ListBox1.SelectedItems.Cast(Of DataRowView)().
Sum(Function(view) CDbl(view("OperationsTime")))
ValueMember
属性只帮助您获取SelectedItem
的值,这有点恼人。这是我不久前编写的一个类,它添加了一个使用ValueMember
的GetItemValue
方法,就像GetItemText
方法对DisplayMember
所做的那样
Public Class ListBoxEx
Inherits ListBox
Public Function GetItemValue(item As Object) As Object
Dim index = Me.Items.IndexOf(item)
If (index <> -1 AndAlso Me.DataManager IsNot Nothing) Then
Return Me.FilterItemOnProperty(Me.DataManager.List(index), Me.ValueMember)
End If
Return Nothing
End Function
End Class
如果您使用该控件而不是常规ListBox
,则可以执行以下操作:
Dim totalOperationsTime As Double
For Each item In ListBoxEx1.SelectedItems
totalOperationsTime += CDbl(ListBoxEx1.GetItemValue(item))
Next
或者这样:
Dim totalOperationsTime = ListBox1.SelectedItems.Cast(Of Object)().
Sum(Function(item) CDbl(ListBoxEx1.GetItemValue(item)))
使用该自定义控件的一个优点是,您不必知道数据源或其项的类型。你只需要知道ValueMember
已经设置好了。
发布于 2018-08-29 23:34:12
我对你的代码做了一些修改。它可以与ListBox一起工作。有关详细信息,请参阅注释。
' "Please Select" doesn't work well in the ListBox, I added it as an option
Private Shared Function GetData(ByVal sql As String, insertPleaseSelect As Boolean) As DataTable
Dim constr As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\hartj\Documents\visual studio 2015\Projects\TIMEMATRIX2.0\TIMEMATRIX2.0\TMX.mdf;Integrated Security=True"
Using con As SqlConnection = New SqlConnection(constr)
Using sda As SqlDataAdapter = New SqlDataAdapter(sql, con)
Dim dt As DataTable = New DataTable()
sda.Fill(dt)
If insertPleaseSelect Then
Dim row As DataRow = dt.NewRow()
row(0) = 1
row(1) = "Please Select"
dt.Rows.InsertAt(row, 0)
End If
Return dt
End Using
End Using
End Function
Private Sub MainHome_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
ComboBox1.DataSource = GetData("SELECT [SizeId], [SizeName] FROM [Size]", True)
ComboBox1.DisplayMember = "SizeName"
ComboBox1.ValueMember = "SizeId"
ComboBox2.Enabled = False
ListBox1.SelectionMode = SelectionMode.MultiSimple ' allow multi-select
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox2.DataSource = Nothing
ComboBox2.Enabled = False
If ComboBox1.SelectedValue.ToString() <> "0" Then
Dim sql As String = String.Format("SELECT [DetailLevelId], [DetailLevelName] FROM [DetailLevel] WHERE [SizeId] = {0}", ComboBox1.SelectedValue)
ComboBox2.DataSource = GetData(sql, True)
ComboBox2.DisplayMember = "DetailLevelName"
ComboBox2.ValueMember = "DetailLevelId"
ComboBox2.Enabled = True
End If
End Sub
Private Sub ComboBox2_SelectionChangeCommitted(sender As Object, e As EventArgs) Handles ComboBox2.SelectionChangeCommitted
ListBox1.DataSource = Nothing
ListBox1.Enabled = False
If ComboBox2.SelectedValue.ToString() <> "0" Then
Dim sql As String = String.Format("SELECT [OperationsId], [OperationsName], [OperationsTime] FROM [Operations] WHERE [DetailLevelId] = {0}", ComboBox2.SelectedValue)
ListBox1.DataSource = GetData(sql, False)
ListBox1.DisplayMember = "OperationsName" ' changed this from ValueMember to DisplayMember
ListBox1.ValueMember = "OperationsTime"
ListBox1.Enabled = True
ListBox1.ClearSelected() ' Every time the ListBox is populated, clear it
End If
End Sub
' Added this handler to respond to user input, not programmatic selection changes
Private Sub ListBox1_Click(sender As Object, e As EventArgs) Handles ListBox1.Click
' Here is the sum
Label9.Text = ListBox1.SelectedItems.OfType(Of DataRowView).Sum(Function(o) CType(o("OperationsTime"), Double))
End Sub
https://stackoverflow.com/questions/52060965
复制相似问题