我有一个简单的子程序,可以从数据库加载一个列表。我希望能够使用相同的代码通过将列表类型定义为公共抽象基类ListControl来加载ListBox和ComboBox,并且看不出我无法理解的原因 - 除了VB.NET不公开/ implements / ListControl中的Items集合。我沮丧地注意到ASP.NET中不是这种情况。目前我的代码很难看,因为我必须检查我传入的列表控件的类型,以便将其转换为具有Items集合的类型。 (由于其他许多原因,我的代码可能很难看,但对我来说这很漂亮)。有没有办法重写代码,以避免必须通过测试和铸造废话? (我把它拆了一下,以便剩下的就是问题所在。)
Sub loadList(ByVal db As SqlDatabase, ByVal strCommandText As String, lstHost As ListControl, Optional bClearList As Boolean = True, Optional bIsListBox As Boolean = True)
If bClearList Then
If bIsListBox Then
CType(lstHost, ListBox).Items.Clear()
Else
CType(lstHost, ComboBox).Items.Clear()
End If
End If
Dim dt As DataTable = db.ExecuteDataSet(db.GetSqlStringCommand(strCommandText)).Tables(0)
For i = 0 To dt.Rows.Count - 1
If bIsListBox Then
CType(lstHost, ListBox).Items.Add(dt.Rows(i)(0).ToString)
Else
CType(lstHost, ComboBox).Items.Add(dt.Rows(i)(0).ToString)
End If
Next
End Sub
答案 0 :(得分:1)
这是因为在winforms中,ListBox对象集合与ComboBox对象集合不同。我能想到的最简单的方法是制作一个像
这样的辅助类Public Class ListHelper
Public Shared Sub Clear(ByRef lst As ListControl)
If TypeOf lst Is ListBox Then
CType(lst, ListBox).Items.Clear()
Else
CType(lst, ComboBox).Items.Clear()
End If
End Sub
Public Shared Sub Add(ByRef lst As ListControl, ByVal itm As Object)
If TypeOf lst Is ListBox Then
CType(lst, ListBox).Items.Add(itm)
Else
CType(lst, ComboBox).Items.Add(itm)
End If
End Sub
End Class
然后在您的代码中,您可以这样做:
Sub loadList(ByVal db As SqlDatabase, ByVal strCommandText As String, _
ByVal lstHost As ListControl, Optional ByVal bClearList As Boolean = True)
If bClearList Then
ListHelper.Clear(lstHost)
End If
Dim dt As DataTable = _
db.ExecuteDataSet(db.GetSqlStringCommand(strCommandText)).Tables(0)
For i = 0 To dt.Rows.Count - 1
ListHelper.Add(lstHost, dt.Rows(i)(0).ToString)
Next
End Sub
编辑:
另一种(可能更好)的方法是使用扩展方法(添加新模块):
Imports System.Runtime.CompilerServices
Module ListExtensions
<Extension()> _
Public Sub AddToItems(ByRef lc As ListControl, ByVal itm As Object)
If TypeOf lc Is ListBox Then
CType(lc, ListBox).Items.Add(itm)
ElseIf TypeOf lc is ComboBox then
CType(lc, ComboBox).Items.Add(itm)
Else
'handle abuse
End If
End Sub
<Extension()> _
Public Sub ClearItems(ByRef lc As ListControl)
If TypeOf lc Is ListBox Then
CType(lc, ListBox).Items.Clear()
ElseIf TypeOf lc is ComboBox Then
CType(lc, ComboBox).Items.Clear()
Else
'handle abuse
End If
End Sub
End Module
在你的代码中最终会变得更整洁:
Sub loadList(ByVal db As SqlDatabase, ByVal strCommandText As String, _
ByVal lstHost As ListControl, Optional ByVal bClearList As Boolean = True)
If bClearList Then
lstHost.ClearItems()
End If
Dim dt As DataTable = _
db.ExecuteDataSet(db.GetSqlStringCommand(strCommandText)).Tables(0)
For i = 0 To dt.Rows.Count - 1
lstHost.AddToItems(dt.Rows(i)(0).ToString)
Next
End Sub
这里我称这些为ClearItems
和AddToItems
,以避免与实例方法产生歧义。 ListControl本身没有.Clear()
或.Add()
,但为了明确起见,最好有一个独特的扩展命名法。