ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 12.07.2002

Diese Seite wurde zuletzt aktualisiert am 12.07.2002
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für den Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

An die Spitze setzen

Zurück...


Anzeige

(-hg) mailto:hg_lvwtvwtopindex@aboutvb.de

Mangels einer TopIndex-Eigenschaft wie bei einer ListBox können Sie bei einem ListView- oder einem TreeView-Steuerelement aus den Microsoft Common Controls nicht so einfach festlegen, welches Element als oberstes angezeigt werden soll.

Mit einem kleinen Trick lässt sich das jedoch leicht erreichen. Denn sowohl ListItems als auch Nodes verfügen über die EnsureVisible-Methode. Diese sorgt dafür, dass ein ListItem bzw. ein Node in den sichtbaren Bereich des Steuerelements gerollt wird. Bei einem Node wird dazu auch noch gegebenenfalls der übergeordnete Zweig geöffnet. Allerdings erscheint das Element dann lediglich am unteren Rand des Steuerelements, und noch nicht wie gewünscht am oberen Rand. Der Trick besteht nun darin, dafür zu sorgen, dass zunächst das unterste Element sichtbar wird, und dann erst das gewünschte. Für ein ListItem könnte das etwa so aussehen:

With ListView1.ListItems
  .Item(.Count).EnsureVisible
  .Item(GewünschterTopIndex).EnsureVisible
End With

Da anders als bei einer einfachen ListBox ein Element nicht nur über einen Index, sondern auch über einen Schlüssel angesprochen werden kann, und da die Elemente selbst auch Objekte sind, wäre vielleicht eine Prozedur praktisch, bei der sich das gewünschte Element sowohl per Index oder Key als auch direkt angeben ließe. Als kleine Verfeinerung könnte das Element auch optional gleich markiert werden (Eigenschaft Selected = True).

Die folgende Funktion leistet dies für ein ListView-Steuerelement. Sie unterdrückt über die API-Funktion LockWindowUpdate auch das Flackern, das bei größeren zu "rollenden" Wegen auftreten könnte. Sie übergeben ihr das ListView-Steuerelement und im zweiten Parameter alternativ den Index, den Schlüssel oder direkt das ListItem, das zum "TopIndex" werden soll. Im dritten. optionalen Parameter Selected legen Sie fest, ob das ListItem auch gleich markiert werden soll.

Private Declare Function LockWindowUpdate Lib "user32" _
 (ByVal hwndLock As Long) As Long

Public Sub LvwTopIndex(Lvw As ListView, TopIndex As Variant, _
 Optional ByVal Selected As Boolean)

  Dim nTopItem As ListItem
  Dim nBottomItem As ListItem
  
  With Lvw
    .ListItems
      Select Case True
        Case IsObject(TopIndex)
          If TypeName(TopIndex) = "IListItem" Then
            Set nTopItem = TopIndex
          Else
            Err.Raise 5
          End If
        Case IsNumeric(TopIndex)
          Select Case VarType(TopIndex)
            Case vbInteger, vbLong
              On Error Resume Next
              Set nTopItem = .Item(TopIndex)
              If Err.Number Then
                Err.Raise Err.Number
              End If
            Case Else
              Err.Raise 5
          End Select
        Case VarType(TopIndex) = vbString
          On Error Resume Next
          Set nTopItem = .Item(TopIndex)
          If Err.Number Then
            Err.Raise Err.Number
          End If
        Case Else
          Err.Raise 5
      End Select
      Set nBottomItem = .Item(.Count)
    End With
    LockWindowUpdate .Parent.hWnd
    If Not (nBottomItem Is nTopItem) Then
      nBottomItem.EnsureVisible
    End If
    With nTopItem
      .EnsureVisible
      .Selected = Selected
    End With
    LockWindowUpdate 0&
  End With
End Sub

Bei einem TreeView ist es allerdings ein wenig aufwändiger, das zunächst sichtbar zu machende unterste Element zu ermitteln. Denn die Index-Reihenfolge stimmt nicht unbedingt mit der vertikalen Reihenfolge der Knoten überein. Außerdem könnte sich der tatsächlich unterste Knoten nicht in einem geöffneten Zweig befinden. Es muss daher zu diesem Zweck der unterste geöffnete Knoten ermittelt werden.

Die folgende Prozedur TvwTopIndex ähnelt im wesentlichen der oben stehenden Prozedur LvwTopIndex und wird im Prinzip genauso aufgerufen.

Public Sub TvwTopIndex(Tvw As TreeView, TopIndex As Variant, _
 Optional ByVal Selected As Boolean)

  Dim nTopNode As Node
  Dim nBottomNode As Node
  Dim nNode As Node
  
  With Tvw.Nodes
    Select Case True
      Case IsObject(TopIndex)
        If TypeName(TopIndex) = "INode" Then
          Set nTopNode = TopIndex
        Else
          Err.Raise 5
        End If
      Case IsNumeric(TopIndex)
        Select Case VarType(TopIndex)
          Case vbInteger, vbLong
            On Error Resume Next
            Set nTopNode = .Item(TopIndex)
            If Err.Number Then
              Err.Raise Err.Number
            End If
          Case Else
            Err.Raise 5
        End Select
      Case VarType(TopIndex) = vbString
        On Error Resume Next
        Set nTopNode = .Item(TopIndex)
        If Err.Number Then
          Err.Raise Err.Number
        End If
      Case Else
        Err.Raise 5
    End Select

Hier wird nun zuerst der erste Knoten ermittelt, der keinen Elternknoten hat, also ein Knoten der obersten Ebene ist:

  For Each nNode In Tvw.Nodes
    If nNode.Parent Is Nothing Then
    Exit For
    End If
  Next

Jetzt wird der letzte Knoten auf gleicher Ebene ermittelt - der am weitesten unten befindliche Knoten der obersten Ebene:

    Set nBottomNode = nNode.LastSibling

Ist er expandiert, wird der erste Kindknoten ermittelt. Ist er nicht expandiert, oder gibt es keinen Kindknoten, bleibt er weiterhin der unterste Knoten. Gibt es Kindknoten, wird wiederum der unterste Knoten auf der Ebene des Kindknotens ermittelt. Die umgebende Schleife wird so lange ausgeführt, bis der unterste sichtbare Knoten ermittelt worden ist:

    Do
      If nBottomNode.Expanded Then
        Set nNode = nBottomNode.Child
        If nNode Is Nothing Then
          Exit Do
        Else
          Set nBottomNode = nNode.LastSibling
        End If
      Else
        Exit Do
      End If
    Loop
    LockWindowUpdate Tvw.Parent.hWnd
    If Not (nBottomNode Is Nothing) Then
      If Not (nBottomNode Is nTopNode) Then
        nBottomNode.EnsureVisible
      End If
    End If
    With nTopNode
      .EnsureVisible
      .Selected = Selected
    End With
    LockWindowUpdate 0&
  End With
End Sub

Modul modLvwTvwTopIndex (lvwtvwtopindex.zip - ca. 1,2 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer