Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Winforms 等同于Microsoft Forms 2.0 ComboBox。Windows窗体和Access窗体中的TopIndex属性?_Winforms_Ms Access_Combobox_Ms Access Forms_Ms Forms - Fatal编程技术网

Winforms 等同于Microsoft Forms 2.0 ComboBox。Windows窗体和Access窗体中的TopIndex属性?

Winforms 等同于Microsoft Forms 2.0 ComboBox。Windows窗体和Access窗体中的TopIndex属性?,winforms,ms-access,combobox,ms-access-forms,ms-forms,Winforms,Ms Access,Combobox,Ms Access Forms,Ms Forms,不推荐使用的Microsoft Forms 2.0控件包含一个组合框,该组合框提供了一个非常宝贵的属性:.TopIndex 根据文档,此属性似乎不适用于Microsoft Access 2019中表单中的标准组合框,也不适用于Windows forms.NET中的标准组合框。此处,组合框继承自ListControl,不提供此属性,而ListBox也继承自ListControl,但是它提供了它 我有很多严重依赖.TopIndex属性的旧代码,现在是将这些代码转移到其他技术的时候了 所以我想知道我是

不推荐使用的Microsoft Forms 2.0控件包含一个组合框,该组合框提供了一个非常宝贵的属性:.TopIndex

根据文档,此属性似乎不适用于Microsoft Access 2019中表单中的标准组合框,也不适用于Windows forms.NET中的标准组合框。此处,组合框继承自ListControl,不提供此属性,而ListBox也继承自ListControl,但是它提供了它

我有很多严重依赖.TopIndex属性的旧代码,现在是将这些代码转移到其他技术的时候了

所以我想知道我是否遗漏了文档中的某些内容,以及是否有一个具有另一个名称的等效属性,我可以使用它来确定组合框的列表部分中哪些项是可见的。我想知道Access 2019中的组合框的情况,我对这个应用程序并不像这里的许多其他应用程序以及Windows窗体中的组合框那样充满敌意

我知道有很多免费和商业控件,包括具有Windows窗体增强功能的组合框。除非我在文档中遗漏了什么,否则我肯定会这样做,或者自己写


然而,在访问2019个表单时,情况完全不同。我找不到一个可以在Access窗体上使用并提供此功能的免费第三方ActiveX/COM组合框。理论上,我可能可以使用.NET编写ActiveX/COM控件,然后在Access表单上使用它,但这似乎很痛苦。

就.NET WinForm ComboBox而言,您没有错过任何东西,因为TopIndex属性的功能没有实现。也就是说,扩展基本ComboBox控件以添加此属性是非常简单的。下面的示例控件应该可以帮助您开始

此控件将侦听器附加到本机ListBox下拉列表,并更新WM_VSCROLL上的TopIndex属性,从而捕获打开消息的初始位置。此外,基本SelectedIndexChange事件用于捕获由于键盘操作pgUp/pgDn、向上/向下箭头引起的更改。TopIndex属性在下拉列表关闭后保留,并在打开下拉列表时重置。该控件还公开TopIndexChanged事件

Imports System.Runtime.InteropServices

Public Class ComboBoxEx : Inherits ComboBox
  Private listBoxListener As ListBoxNativeWindow
  Public Event TopIndexChanged As EventHandler(Of ComboBoxTopIndexArg)

  Private _TopIndex As Int32 = -1

  Public Sub New()
    MyBase.New
    listBoxListener = New ListBoxNativeWindow(Me)
  End Sub

  Public Property TopIndex As Int32
    Get
      Return _TopIndex
    End Get
    Private Set(value As Int32)
      If value <> _TopIndex Then
        _TopIndex = value
        RaiseEvent TopIndexChanged(Me, New ComboBoxTopIndexArg(value))
      End If
    End Set
  End Property

  Protected Overrides Sub OnDropDown(e As EventArgs)
    _TopIndex = -1 ' reset on opening the listbox
    MyBase.OnDropDown(e)
  End Sub

  Private Class ListBoxNativeWindow : Inherits NativeWindow
    Private listBoxHandle As IntPtr
    Private TopIndex As Int32
    Private parent As ComboBoxEx

    Public Sub New(ByVal parent As ComboBoxEx)
      Me.parent = parent
      WireParent()
      If parent.IsHandleCreated Then
        GetListBoxHandle()
        AssignHandle(listBoxHandle)
      End If
    End Sub

    Private Sub WireParent()
      AddHandler parent.HandleCreated, AddressOf Me.OnHandleCreated
      AddHandler parent.HandleDestroyed, AddressOf Me.OnHandleDestroyed
      AddHandler parent.SelectedIndexChanged, AddressOf UpdateTopIndexOnIndexChanged
    End Sub

    Private Sub OnHandleCreated(ByVal sender As Object, ByVal e As EventArgs)
      GetListBoxHandle()
      AssignHandle(listBoxHandle)
    End Sub

    Private Sub OnHandleDestroyed(ByVal sender As Object, ByVal e As EventArgs)
      ReleaseHandle()
    End Sub

    Private Sub UpdateTopIndexOnIndexChanged(sender As Object, e As EventArgs)
      SetParentTopIndex()
    End Sub

    Private Sub GetListBoxHandle()
      Const CB_GETCOMBOBOXINFO As Int32 = &H164
      Dim info As New ComboBoxInfo
      info.cbSize = Marshal.SizeOf(info)
      Dim res As Boolean = SendMessage(Me.parent.Handle, CB_GETCOMBOBOXINFO, Nothing, info)
      listBoxHandle = info.hwndList
    End Sub

    Protected Overrides Sub WndProc(ByRef m As Message)
      Const WM_VSCROLL As Int32 = &H115
      Const LB_SETCARETINDEX As Int32 = &H19E

      MyBase.WndProc(m)
      If m.Msg = WM_VSCROLL OrElse m.Msg = LB_SETCARETINDEX Then
        SetParentTopIndex()
      End If
    End Sub

    Private Sub SetParentTopIndex()
      Const LB_GETTOPINDEX As Int32 = &H18E
      parent.TopIndex = SendMessage(listBoxHandle, LB_GETTOPINDEX, IntPtr.Zero, IntPtr.Zero)
    End Sub
  End Class

  Public Class ComboBoxTopIndexArg : Inherits EventArgs
    Public Sub New(topIndex As Int32)
      Me.TopIndex = topIndex
    End Sub

    Public ReadOnly Property TopIndex As Int32
  End Class

#Region "NativeMethods"
  <StructLayout(LayoutKind.Sequential)>
  Private Structure ComboBoxInfo
    Public cbSize As Int32
    Public rcItem As RECT
    Public rcButton As RECT
    Public stateButton As IntPtr
    Public hwndCombo As IntPtr
    Public hwndEdit As IntPtr
    Public hwndList As IntPtr
  End Structure

  <StructLayout(LayoutKind.Sequential)>
  Private Structure RECT
    Public Left, Top, Right, Bottom As Int32
  End Structure

  <DllImport("user32.dll")>
  Private Shared Function SendMessage(hWnd As IntPtr, Msg As Int32, wParam As IntPtr, <Out()> ByRef lParam As ComboBoxInfo) As Boolean
  End Function

  <DllImport("user32.dll")>
  Private Shared Function SendMessage(hWnd As IntPtr, Msg As Int32, wParam As IntPtr, lParam As IntPtr) As Int32
  End Function
#End Region

End Class

我让您将其包装在ActiveX公开包装中,以便在Access中使用。使用中的模板执行此操作相当容易。请注意,这些模板是使用Any CPU平台设置的,您需要将其更改为x86。

我不确定TopIndex在组合框中的用途,您可能只需要选择的索引。如果您想显示一个特定的项目>MaxDropDownItems,设置comboBox1.SelectedIndex=N,我认为您可以使用类似的功能;comboBox1.DroppedDown=true;在列表框中,TopIndex LB_GETTOPINDEX、LB_SETTOPINDEX用于在重新创建LB句柄时重新创建以前的布局。在组合框中,它的dropcrowd总是新的。事实证明,这个属性对于实现带有分页的组合框非常有用。我有一个应用程序,其中大约有40万个可能的条目可以加载到combobox中,当然这在性能和可用性方面没有任何意义。因此,我从50个条目开始,根据需要加载其余条目。这里的问题是,用户可以使用鼠标滚轮以及PgUp、PgDown、Cursor等滚动combobox下拉列表。您可以使用LINQ或DataTable过滤combobox.DataSource。DefaultView filters+LINQ,最终这些技术不是用于客户端过滤吗?当然,我不想从数据库中提取所有可能的记录,然后在客户端对它们进行过滤。此外,我无法想象过滤器在这里能起到什么作用。我的问题是根据用户的滚动来确定我应该在组合框的列表部分获取/显示哪部分数据。哇,非常感谢。我认为这个答案没有什么可补充的——绝对是个好工作!几行代码显示了如何捕获任何事件,再加上对一个有价值的工具包的引用,直到现在我才知道这个工具包只使用了.NET几次,而且只有一次我在没有工具箱帮助的情况下将.NET代码放入ActiveX中。如果可以的话,我会投上一百次。