1

我有一个从数据库加载列表的简单子程序。我希望能够通过将列表类型定义为通用抽象基类 ListControl 来使用相同的代码来加载 ListBox 和 ComboBox,并且看不出为什么我不能 - 除了 VB.NET 不公开/implement/whatever 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
4

1 回答 1

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

在这里,我调用了这些ClearItemsAddToItems以避免与实例方法产生歧义。ListControl 本身没有.Clear().Add()但为了明确起见,最好有一个独特的扩展命名法。

于 2012-04-11T16:26:39.327 回答