13. Jun 2022
Lesedauer 7 Min.
Google-Chrome-Bookmarks
Ein eigenes Steuerelement für Webinhalte, Teil 10
Für den Umstieg auf die Chromium-Engine bietet es sich zunächst an, die bestehenden Lesezeichen von Google Chrome zu importieren.

In den vorangegangenen Folgen dieser Artikelserie wurde ein Webbrowser-Steuerelement namens BrowserCtl realisiert, das auf dem Windows-Forms-Steuerelement WebBrowser – und damit auf der Engine des Internet Explorer – basiert und mit einer erweiterten Benutzerumgebung ausgestattet wurde. Im Anschluss daran wurden eigenständige Steuerelemente entwickelt, mit deren Hilfe Sie die Favoriten des Internet Explorer einlesen und komfortabel zur Auswahl bereitstellen [1]. Zusätzlich wurde eine Funktion implementiert, um selbst Favoriten im Internet-Explorer-Format anzulegen.Auch Google Chrome stellt Funktionen zur Anlage und Verwaltung von Favoriten bereit. In Chrome werden die Favoriten über Lesezeichen (Bookmarks) verwaltet (Bild 1). Um Zugriff darauf zu erhalten, nutzen Sie die Menüfunktionen – siehe [2] und [3]) –, die durch Anwahl der drei Punkte im rechten oberen Bereich der Adressleiste angeboten werden. In diesem Menü werden die Lesezeichen im gleichnamigen Untermenü strukturiert und ordnerbasiert angezeigt. Verglichen mit der Strukturansicht im Internet Explorer ist diese Menüansicht allerdings weniger übersichtlich und zudem schwerer zu handhaben. Ein permanentes Anzeigen des Menüs wird nicht unterstützt. Es fehlt zudem das wahlweise und parallele Offenlegen mehrerer Ordnerinhalte. Aus diesem Grunde sollen die Lesezeichen von Google Chrome später auch mit dem Internet Explorer verwaltet werden. Bevor es allerdings so weit ist, sind zunächst die Lesezeichen einzulesen und zu importieren.

In Google Chromewerden Favoriten über Lesezeichen verwaltet(Bild 1)
Autor
Die Lesezeichen werden von Google Chrome auch über eine Lesezeichenleiste bereitgestellt, sofern diese aktiviert wurde (Bild 2). Das Aktivieren erfolgt im Google-Chrome-Menü über den Eintrag Lesezeichenleiste anzeigen. Auch diese Anzeigevariante kann allerdings nicht mit der Strukturansicht konkurrieren.

Die Lesezeichenleistevon Google Chrome(Bild 2)
Autor
Grundlagen zu Chrome-Bookmarks
Bevor Sie sich um die Lesezeichen kümmern können, müssen Sie sich zuerst der Speicherung unter Chrome zuwenden. Sie benötigen Informationen zum Speicherort, zum Speicherformat sowie zum Namen der Datei, in der die Lesezeichen abgelegt werden. Sie finden die Bookmarks im folgenden Ordner:
C:<span class="hljs-symbol">\U</span>sers<span class="hljs-symbol">\[</span>Benutzername]<span class="hljs-symbol">\A</span>ppData<span class="hljs-symbol">\L</span>ocal<span class="hljs-symbol">\G</span>oogle<span class="hljs-symbol">\</span>
<span class="hljs-symbol"> </span> Chrome<span class="hljs-symbol">\U</span>ser Data<span class="hljs-symbol">\D</span>efault
In diesem Pfad ist der [Benutzername] durch den tatsächlichen aktiven Benutzernamen zu ersetzen. Die Datendatei trägt den Namen Bookmarks und verwendet kein Dateikürzel. Laden Sie diese Datei in einen Texteditor, erkennen Sie, dass für Lesezeichen ein JSON-Format verwendet wird. Einen Auszug aus einer Bookmark-Datendatei sehen Sie in Listing 1.
Listing 1: JSON-Struktur einer Bookmark-Datei – Teil 1
{ <br/> <span class="hljs-string">"checksum"</span>: <span class="hljs-string">"77a1c9f00acf35d68b219197e2eec43b"</span>, <br/> <span class="hljs-string">"roots"</span>: { <br/> <span class="hljs-string">"bookmark_bar"</span>: { <br/> <span class="hljs-string">"children"</span>: [ { <br/> <span class="hljs-string">"children"</span>: [ { <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13286818409413588"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"5ef3158f-2c95-4618-87a8-</span><br/><span class="hljs-string"> adcff66279b4"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"476"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Altes Kontextmenü öffnen </span><br/><span class="hljs-string"> Windows 11 Deskmodder Wiki"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"url"</span>, <br/> <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://www.deskmodder.de/wiki/</span><br/><span class="hljs-string"> index.php?title=</span><br/><span class="hljs-string"> Altes_Kontextmen%C3%BC_%C3%B6ffnen."</span> <br/> }, { <br/> ... <br/> } ], <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13286818436571635"</span>, <br/> <span class="hljs-string">"date_modified"</span>: <span class="hljs-string">"13293019062394117"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"f1507a59-e6a0-42e7-863b-</span><br/><span class="hljs-string"> f4d10ff2864b"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"477"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Win11 Tuning"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"folder"</span> <br/> }, { <br/> <span class="hljs-string">"children"</span>: [ { <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13270300778845295"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"467ff933-11ea-463c-aeca-</span><br/><span class="hljs-string"> 853f8a0587e5"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"330"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Ferienhaus in Dänemark an der </span><br/><span class="hljs-string"> Nordsee - Urlaub bei Esmark"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"url"</span>, <br/> <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://esmark.de/suche/"</span> <br/> }, { <br/> ... <br/> } ], <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13270300815501791"</span>, <br/> <span class="hljs-string">"date_modified"</span>: <span class="hljs-string">"13287324511183956"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"6d1c436a-7ea9-4bfe-bed2-</span><br/><span class="hljs-string"> 23cff9eb4a3a"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"331"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Dänemark"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"folder"</span> <br/> }, { <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13254190477467234"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"4d378c62-fed3-47f7-</span><br/><span class="hljs-string"> 8e46-7c33d0a3162d"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"227"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Gmail"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"url"</span>, <br/> <span class="hljs-string">"url"</span>: <span class="hljs-string">"https://accounts.google.com/b/0/</span><br/><span class="hljs-string"> AddMailService"</span> <br/> }, { <br/> ... <br/> }, { <br/> <span class="hljs-string">"children"</span>: [ { <br/> ... <br/> } ], <br/> ... <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"folder"</span> <br/> }, { <br/> }, <br/> <span class="hljs-string">"other"</span>: { <br/> <span class="hljs-string">"children"</span>: [ ], <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13172502690915010"</span>, <br/> <span class="hljs-string">"date_modified"</span>: <span class="hljs-string">"0"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"82b081ec-3dd3-529c-8475-</span><br/><span class="hljs-string"> ab6c344590dd"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"2"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Weitere Lesezeichen"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"folder"</span> <br/> }, <br/> <span class="hljs-string">"synced"</span>: { <br/> <span class="hljs-string">"children"</span>: [ ], <br/> <span class="hljs-string">"date_added"</span>: <span class="hljs-string">"13172502690915010"</span>, <br/> <span class="hljs-string">"date_modified"</span>: <span class="hljs-string">"0"</span>, <br/> <span class="hljs-string">"guid"</span>: <span class="hljs-string">"4cf2e351-0e85-532b-bb37-</span><br/><span class="hljs-string"> df045d8f8d0f"</span>, <br/> <span class="hljs-string">"id"</span>: <span class="hljs-string">"3"</span>, <br/> <span class="hljs-string">"name"</span>: <span class="hljs-string">"Mobile Lesezeichen"</span>, <br/> <span class="hljs-string">"type"</span>: <span class="hljs-string">"folder"</span> <br/> } <br/> }, <br/> <span class="hljs-string">"sync_metadata"</span>: <span class="hljs-string">"..."</span>, <br/> <span class="hljs-string">"version"</span>: <span class="hljs-number">1</span> <br/>}
Dieses Format soll zur vereinfachten Nutzung zunächst in ein strukturiertes Objektformat überführt werden. Dafür gilt es die Datenstruktur zunächst genau zu analysieren. In der Datei Bookmarks finden Sie die Ordnerstruktur inklusive der Ordnernamen für die inhaltliche Gliederung sowie die zugehörigen URLs. Ebenso wie in der Internet-Explorer-Ordnerstruktur werden hier die Ordner nach Bedarf geschachtelt. Informationen zu Bildsymbolen finden sich in der Textdatei nicht. Hier kommen also nur Standardsymbole zum Einsatz (zum Beispiel favicon.ico) oder Symbole, die über <link rel=“shortcut icon“ href=“URL“ /> adressierbar sind. Gegebenenfalls lassen sich die Symbole auch über folgende Adresse abfragen:
https:<span class="hljs-regexp">//</span>www.google.com<span class="hljs-regexp">/s2/</span>favicons?domain_url=
Dazu übergeben Sie den URL, wie im folgenden Beispiel gezeigt wird:
https:<span class="hljs-regexp">//</span>www.google.com<span class="hljs-regexp">/s2/</span>favicons?
domain_url=https:<span class="hljs-regexp">//</span>www.dotnetpro.de
Eine Objekthierarchie für Lesezeichen
Das Schaubild in Bild 3 veranschaulicht die Objektstruktur, die sich aus der Datendatei Bookmarks ergibt. Der Übersichtlichkeit halber sind in der Grafik alle Objekte, Auflistungen (Kollektionen), Eigenschaften und Methoden farbig gekennzeichnet. Das Basisobjekt trägt den Namen ChromeBookmarks. Es verwaltet die Eigenschaften checksum (Prüfsumme), version (Versionsnummer) und Metadaten für die Synchronisation (sync_metadata). Die Metadaten werden an dieser Stelle nicht benötigt und später im Rahmen der Verarbeitung ignoriert. Die Hauptelemente (Wurzelelemente oder Roots) werden über eine Kollektion des Typs roots verwaltet. Hier finden sich die drei Hauptelemente bookmark_bar (Lesezeichenleiste), other (andere) und synced (zwischen Geräten synchronisierte Inhalte). Alle Kollektionen stellen zur Auflistungsverwaltung die Methoden Add, AddRange, Insert, Remove, Clear, IndexOf und Item bereit.
Nachgebildete Objekthierarchieder Google-Chrome-Bookmarks(Bild 3)
Autor
Jedes Wurzelelement der Auflistung roots ist selbst vom Objekttyp root. Darüber werden der Name (name), alle untergeordneten Ordner inklusive der zugehörigen Webadressen als Auflistung (FolderDatas) sowie direkt zugeordnete URLs als Auflistung verwaltet (childrens). Das Element zur Verwaltung eines einzelnen Lesezeichenordners ist das Objekt FolderData. Diesem werden alle untergeordneten URLs mitsamt Eigenschaften über die Kollektion childrens zugeordnet. Ein einzelnes Objekt des Typs children verwaltet Informationen zum Datum des Hinzufügens (date_added), eine eindeutige GUID (guid), eine Kennung (id), einen Namen (name, entspricht der Menübezeichnung), einen Typ (type, immer die Zeichenkette url) sowie den zugeordneten Uniform Resource Locator (url). Zum Ordner selbst werden über das Objekt FolderData folgende Daten verwaltet: das Datum des Hinzufügens (date_added), das Datum der letzten Änderung (date_modified), eine eindeutige GUID (guid), eine Kennung (id), ein Name (name, entspricht der Menübezeichnung), ein Typ (type, immer die Zeichenkette folder) sowie eine gegebenenfalls untergeordnete SubFolderDatas-Auflistung, über die geschachtelte Menüebenen des Typs DataFolders verwaltbar sind.Für die Elementverwaltung der Kollektionen childrens und DataFolders werden erneut die bereits oben genannten Methoden angeboten.
Klassen für Lesezeichen
Um die Objekthierarchie entsprechend Bild 3 zu definieren und programmintern zu verwalten, sind die Klassen ChromeBookmarks, Root, Roots, FolderData, FolderDatas, Children und Childrens zu definieren. Sie finden alle genannten Klassen in der Projektdatei BrowserFunctions.vb der Steuerelementbibliothek ExtendedControlsLib. Bild 4 zeigt die Klassen mitsamt Schnittstellenelementen und deren Datentypen. Bei den Methoden werden auch die genutzten Datentypen angezeigt. Alle Bezeichner werden innerhalb der Klassen entsprechend den Bezeichnern in der Bookmarks-Datei vergeben, sodass sich Bezüge im direkten Vergleich herstellen lassen.Die Klasse ChromeBookmarks

Alle neuen Klassenzur Lesezeichenverwaltung finden sich in der Datei BrowserFunctions.vb der Steuerelementbibliothek ExtendedControlLib(Bild 4)
Autor
Die Klasse ChromeBookmarks verwaltet die Prüfsumme (checksum), die Versionsnummer zum Lesezeichenformat (version) sowie die Auflistung aller Wurzelelemente (roots) über öffentliche Eigenschaften. Die Metadaten werden an dieser Stelle nicht benötigt und dementsprechend ist die zugehörige Eigenschaft sync_metadata auskommentiert. Prüfsumme und Versionsnummer werden als Zeichenketten verwaltet. Die Auflistung der Wurzelelemente roots ist vom Typ Roots. Für die korrekte Verarbeitung wird die Auflistung roots unmittelbar mit New Roots instanziert.
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> ChromeBookmarks
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> checksum
<span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> roots
<span class="hljs-keyword">As</span> <span class="hljs-keyword">New</span> Roots
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> version <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>
<span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
Die Klassen Root und Roots
Über die Klasse Root wird ein einzelnes Wurzelelement zur Lesezeichenverwaltung verarbeitet. Der Name des Elements wird über die Zeichenketteneigenschaft Name verwaltet. Jedem Wurzelelement können ein oder mehrere URLs zugewiesen werden. Diese werden über die Auflistung Childrens verwaltet. In jedem Wurzelelement können Unterordner des Typs FolderDatas eingerichtet werden, die hier über die gleichnamige Eigenschaft verwaltet werden. Für die korrekte Verarbeitung werden die Auflistungen Childrens und FolderDatas erneut mit New instanziert.
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> Root
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> Name <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> FolderDatas
<span class="hljs-keyword">As</span> <span class="hljs-keyword">New</span> FolderDatas
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> Childrens <span class="hljs-keyword">As</span>
<span class="hljs-keyword">New</span> Childrens
<span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
Die Auflistungsklasse Roots fasst alle Wurzelelemente zusammen (Listing 2). Sie wird von CollectionBase abgeleitet und definiert die Methoden Add, AddRange, Insert, Remove, Clear, IndexOf und Item:
Listing 2: Die Auflistungsklasse Roots
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> Roots <br/> <span class="hljs-keyword">Inherits</span> CollectionBase <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> Add(<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Root) <span class="hljs-keyword">As</span> Root <br/> List.Add(Item) <br/> <span class="hljs-keyword">Return</span> Item <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Function</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> AddRange(<span class="hljs-keyword">ByVal</span> Items() <span class="hljs-keyword">As</span> Root) <br/> <span class="hljs-keyword">For</span> <span class="hljs-keyword">Each</span> Item <span class="hljs-keyword">As</span> Root <span class="hljs-keyword">In</span> Items <br/> List.Add(Item) <br/> <span class="hljs-keyword">Next</span> <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Insert(<span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>, <br/> <span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Root) <br/> List.Insert(Index, Item) <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Remove(<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Root) <br/> List.Remove(Item) <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Overloads</span> <span class="hljs-keyword">Sub</span> Clear() <br/> <span class="hljs-keyword">MyBase</span>.Clear() <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> IndexOf(<br/> <span class="hljs-keyword">ByVal</span> value <span class="hljs-keyword">As</span> Root) <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span> <br/><br/> <span class="hljs-keyword">Return</span> List.IndexOf(value) <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Function</span> <br/><br/> <span class="hljs-keyword">Default</span> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">ReadOnly</span> <span class="hljs-keyword">Property</span> Item(<br/> <span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>) <span class="hljs-keyword">As</span> Root <br/><br/> <span class="hljs-keyword">Get</span> <br/> <span class="hljs-keyword">Try</span> <br/> <span class="hljs-keyword">Return</span> <span class="hljs-built_in">CType</span>(List(Index), Root) <br/> <span class="hljs-keyword">Catch</span> <br/> <span class="hljs-keyword">Return</span> <span class="hljs-literal">Nothing</span> <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Try</span> <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Get</span> <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Property</span> <br/><span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
- Add: Einzelnes Element (Item) des Typs Root der Auflistung hinzufügen.
- AddRange: Datenfeld mit Wurzelelementen des Typs Root der Auflistung hinzufügen.
- Insert: Einzelnes Element (Item) des Typs Root am angegebenen Index der Auflistung einfügen.
- Remove: Einzelnes Element (Item) des Typs Root am angegebenen Index aus der Auflistung entfernen.
- Clear: Gesamte Auflistung mit allen Root-Elementen löschen.
- IndexOf: Indexwert zu einem angegebenen Wurzelelement (Item) abrufen.
- Item: Wurzelelement zu einem angegebenen Indexwert abrufen.
Die Klassen FolderData und FolderDatas
Jedes Wurzelelement Root kann ein oder mehrere Ordner (Folder) mitsamt den zugehörigen URL-Einträgen, aber auch direkt zugeordnete URL-Einträge verwalten. Für die direkte URL-Zuordnung im Wurzelelement kommt die Auflistungseigenschaft Childrens des Typs Childrens und für die untergeordnete Verwaltung von Ordnern und deren zugeordneten URL-Einträgen die Auflistungseigenschaft SubFolderDatas des Typs FolderDatas zum Einsatz (Listing 3). Beide Kollektionen werden für den direkten Einsatz unmittelbar instanziert. Zusätzliche Zeichenketteneigenschaften verwalten das Datum der Ordneranlage (date_added), das Datum der letzten Änderung (date_added), eine GUID (guid), eine Kennung (id), einen Ordernamen (name) sowie den Ordnertyp (type, hier immer folder). Die Klasse selbst definiert zwei New-Konstruktoren. Ohne Parameterangabe wird das Objekt lediglich neu instanziert. Mit den Parametern lassen sich die Eigenschaften komplett setzen.Listing 3: Die Klasse FolderData
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> FolderData <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> Childrens <span class="hljs-keyword">As</span> <span class="hljs-keyword">New</span> Childrens <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> date_added <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> date_modified <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> guid <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> id <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> name <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> type <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> SubFolderDatas <span class="hljs-keyword">As</span> <span class="hljs-keyword">New</span> FolderDatas <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> <span class="hljs-keyword">New</span>(Childrens <span class="hljs-keyword">As</span> Childrens, <br/> date_added <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, date_modified <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, <br/> guid <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, id <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, <br/> name <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, type <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, <br/> SubFolderDatas <span class="hljs-keyword">As</span> FolderDatas) <br/> <span class="hljs-keyword">Me</span>.Childrens = Childrens <br/> <span class="hljs-keyword">Me</span>.date_added = date_added <br/> <span class="hljs-keyword">Me</span>.date_modified = date_modified <br/> <span class="hljs-keyword">Me</span>.guid = guid <br/><br/> <span class="hljs-keyword">Me</span>.id = id <br/> <span class="hljs-keyword">Me</span>.name = name <br/> <span class="hljs-keyword">Me</span>.type = type <br/> <span class="hljs-keyword">Me</span>.SubFolderDatas = SubFolderDatas <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> <span class="hljs-keyword">New</span>() <br/> <span class="hljs-keyword">MyBase</span>.<span class="hljs-keyword">New</span>() <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
So wie die Auflistungsklasse Roots die Objekte des Typs Root zusammenfasst, führen Sie die Objekte des Typs FolderData in der Auflistungsklasse FolderDatas zusammen. Da die Auflistungsklassen Roots und FolderDatas sich lediglich hinsichtlich ihrer Datentypen unterscheiden, sind im nachfolgenden Quelltextauszug zur Klasse FolderDatas lediglich die Prozedurköpfe der implementierten Methoden wiedergegeben. Die Methoden wurden bereits bei der Klasse Roots beschrieben. Die FolderDatas-Auflistungen kommen innerhalb der Objekthierarchie zur Lesezeichenverwaltung mehrfach zum Einsatz.
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> FolderDatas
<span class="hljs-keyword">Inherits</span> CollectionBase
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> Add(
<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> FolderData) <span class="hljs-keyword">As</span> FolderData
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> AddRange(<span class="hljs-keyword">ByVal</span> Items() <span class="hljs-keyword">As</span> FolderData)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Insert(<span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>,
<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> FolderData)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Remove(<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> FolderData)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Overloads</span> <span class="hljs-keyword">Sub</span> Clear()
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> IndexOf(
<span class="hljs-keyword">ByVal</span> value <span class="hljs-keyword">As</span> FolderData) <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>
<span class="hljs-keyword">Default</span> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">ReadOnly</span> <span class="hljs-keyword">Property</span> Item(
<span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>) <span class="hljs-keyword">As</span> FolderData
<span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
Die Klassen Children und Childrens
Alle URL-Einträge werden mitsamt zugehörigen Eigenschaften über Objekte des Typs Children verwaltet. Als öffentliche Zeichenketteneigenschaften definiert sind date_added, guid, id, name (Bezeichner = Menütitel), type (Standard-String: url) und url (Webadresse). Die Klasse bekommt ebenfalls zwei New-Konstruktoren. Ohne Parameterangabe wird das Objekt lediglich instanziert, mit Parametern lassen sich die zugeordneten Eigenschaften setzen (Listing 4).Listing 4: Die Klasse Children
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> Children <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> date_added <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> guid <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> id <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> name <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> type <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Property</span> url <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> <span class="hljs-keyword">New</span>(date_added <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, <br/> guid <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, id <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, <br/> name <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, type <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>, url <span class="hljs-keyword">As</span> <span class="hljs-built_in">String</span>) <br/><br/> <span class="hljs-keyword">Me</span>.date_added = date_added <br/> <span class="hljs-keyword">Me</span>.guid = guid <br/> <span class="hljs-keyword">Me</span>.id = id <br/> <span class="hljs-keyword">Me</span>.name = name <br/> <span class="hljs-keyword">Me</span>.type = type <br/> <span class="hljs-keyword">Me</span>.url = url <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><br/> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> <span class="hljs-keyword">New</span>() <br/> <span class="hljs-keyword">MyBase</span>.<span class="hljs-keyword">New</span>() <br/> <span class="hljs-keyword">End</span> <span class="hljs-keyword">Sub</span> <br/><span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
Alle URL-Einträge mitsamt deren Eigenschaften verwalten Sie über die Auflistungsklasse Childrens. Da sich die Auflistungsklassen Roots,FolderDatas und Childrens lediglich anhand ihrer Datentypen unterscheiden, sind im nachfolgenden Quelltextauszug zur Klasse Childrens lediglich die Prozedurköpfe der implementierten Methoden wiedergegeben.
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Class</span> Childrens
<span class="hljs-keyword">Inherits</span> CollectionBase
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> Add(
<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Children) <span class="hljs-keyword">As</span> Children
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> AddRange(
<span class="hljs-keyword">ByVal</span> Items() <span class="hljs-keyword">As</span> Children)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Insert(<span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>,
<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Children)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Sub</span> Remove(<span class="hljs-keyword">ByVal</span> Item <span class="hljs-keyword">As</span> Children)
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Overloads</span> <span class="hljs-keyword">Sub</span> Clear()
<span class="hljs-keyword">Public</span> <span class="hljs-keyword">Function</span> IndexOf(
<span class="hljs-keyword">ByVal</span> value <span class="hljs-keyword">As</span> Children) <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>
<span class="hljs-keyword">Default</span> <span class="hljs-keyword">Public</span> <span class="hljs-keyword">ReadOnly</span> <span class="hljs-keyword">Property</span> Item(
<span class="hljs-keyword">ByVal</span> Index <span class="hljs-keyword">As</span> <span class="hljs-built_in">Integer</span>) <span class="hljs-keyword">As</span> Children
<span class="hljs-keyword">End</span> <span class="hljs-keyword">Class</span>
Prinzipiell können Sie die JSON-Daten per Deserialisierung einlesen. Leichte Abweichungen in der Objekthierarchie führen dann aber mitunter zu schwer lokalisierbaren Fehlern. Dies können Sie durch den Einsatz benutzerdefinierter Methoden zur Datenauswertung und -aufbereitung umgehen. Die dafür erforderlichen Methoden werden im nächsten Heft detailliert vorgestellt.
Fussnoten
- Andreas Maslo, Endspurt, Ein eigenes Steuerelement für Webinhalte, Teil 9, dotnetpro 6/2022, Seite 166 ff., http://www.dotnetpro.de/A2206BasicInstinct
- Google-Lesezeichen erstellen, ansehen und bearbeiten, http://www.dotnetpro.de/SL2207BasicInstinct1
- Google-Lesezeichen exportieren, http://www.dotnetpro.de/SL2207BasicInstinct2