PBToolboxAI v5 ← Site

treeview — u_pbt_treeview #

← Komponentenreferenz · Inhalt des Handbuchs

treeview zeigt Daten als Baum: Knoten, die andere enthalten, über ihren Chevron geöffnet und geschlossen, mit einem Bild, einem Badge, einem Kontrollkästchen mit drei Zuständen und einer Einfach- oder Mehrfachauswahl. Sobald er eine Spalte erhält, wird er zur Baumliste (TreeList): Die erste Spalte trägt den Baum, die anderen zeigen die Felder jedes Knotens, sortierbar per Klick auf ihre Kopfzeile. Ein Zweig kann Kinder versprechen, die er erst beim Öffnen liest; der Benutzer benennt einen Knoten um (F2) und zieht ihn an eine andere Stelle, wobei Ihre Anwendung vorher ablehnen kann; eine Suche behält nur, was passt. Der Baum wird von Hand oder aus einem hierarchischen DataStore gefüllt (eine Zeile nennt ihren Elternknoten) und kann dorthin zurückschreiben, was der Benutzer ändert.

▶ Live ansehen — Demoanwendung, Kachel Tree view: die Vorschau, der zugehörige Code und diese Seite, nebeneinander.


Auf einen Blick #

Userobjectu_pbt_treeview
Elementklassenn_pbt_treeview_node (of_node(keys)), n_pbt_treeview_column (of_column(key))
Dient zuEin Ordnerbaum, ein Organigramm, Produktkategorien, anzuhakende Rechte, eine Stückliste mit ihren Mengen
PrinzipEin Knoten hat einen unter seinem Elternknoten eindeutigen Schlüssel; seine Adresse verbindet die Schlüssel seiner Ebenen mit / ("europe/france")
Opt-in-Optionenib_checkboxes, ib_editable, ib_drag_drop, ib_veto_changes, ib_veto_selection, ib_veto_toggle, ib_single_expand, ib_parents_first, ib_toolbar, ib_show_lines, ib_write_back, ib_allow_drop
Grenze im DemomodusDie ersten 8 Knoten jeder Ebene werden gezeichnet, unter jedem Elternknoten, in der Reihenfolge des Modells, und 200 Knoten im ganzen Baum, die zuerst hinzugefügten (ein ausgeblendeter Knoten zählt, Lose und Gruppen eingeschlossen; ein Gesamtwert zählt nie, was die Grenze verbirgt) — siehe Der Demomodus

Schnellstart #

// Two levels : a continent, then its countries (the parent is added first)
uo_tree.of_add_node(/*keys*/ "europe", /*text*/ "Europe")
uo_tree.of_add_node(/*keys*/ "europe/france", /*text*/ "France")
uo_tree.of_add_node(/*keys*/ "europe/italy", /*text*/ "Italy")

// Open the continent : its countries show
uo_tree.of_node(/*keys*/ "europe").ib_expanded = true
// event ue_node_opened of uo_tree : (string as_keys)
// A double click or Enter on a node : your own window shows it
OpenWithParm(w_country, as_keys)

Eine Adresse pro Knoten #

Ein Knoten wird über seine Adresse bezeichnet: die Schlüssel seiner Ebenen, mit / verbunden. "europe" steht oben, "europe/france" in "europe" — der Elternknoten wird zuerst hinzugefügt. Ein Schlüssel ist unter seinem Elternknoten eindeutig: "europe/paris" und "usa/paris" sind zwei Knoten. Eine schon vergebene Adresse, ein unbekannter Elternknoten, eine leere Ebene, ein Schlüssel mit | oder der mit __ beginnt: Das Hinzufügen gibt -5 zurück und of_get_last_error sagt warum. of_insert_node setzt einen Knoten zwischen seine Geschwister (Position ab 1 gezählt), of_move_node verschiebt ihn mit seinem Teilbaum unter einen anderen Elternknoten ("" = ganz oben): Seine Adresse ändert sich, und die an der alten Adresse geholten Handles werden sofort freigegeben (ein danach an der neuen geholter Handle bleibt gültig). Um den Baum zu durchlaufen: of_count() und of_keys_at(n) für die oberste Ebene, of_count(adresse) und of_keys_at(adresse, n) für die Kinder eines Knotens — das die vollständige Adresse liefert, so wiederverwendbar.

// Local variables
long ll_i

// Paris first among the cities of France, then Italy moved under a new region
uo_tree.of_add_node(/*keys*/ "europe/france/lyon", /*text*/ "Lyon")
uo_tree.of_insert_node(/*keys*/ "europe/france/paris", /*text*/ "Paris", /*image*/ "", /*position*/ 1)
uo_tree.of_add_node(/*keys*/ "south", /*text*/ "Southern Europe")
uo_tree.of_move_node(/*keys*/ "europe/italy", /*to_parent_keys*/ "south", /*position*/ 1)

// The children of France, by their whole address
for ll_i = 1 to uo_tree.of_count(/*keys*/ "europe/france")
    lb_cities.AddItem(uo_tree.of_keys_at(/*keys*/ "europe/france", /*index*/ ll_i))
next

Öffnen, auswählen, anhaken #

Ein Knoten öffnet sich über seinen Chevron, einen Doppelklick, die Tastatur oder Ihren Code (ib_expanded seines Handles, of_expand_all, of_collapse_all, of_expand_to_level, of_scroll_to_node, was of_select_node öffnet; of_clear_children schließt): Jedes davon löst ue_node_toggled aus, dann ue_layout_changed. Die Auswahl folgt is_selection_mode: ein Knoten (SELECT_SINGLE, der Standard), mehrere mit Strg und Umschalt wie im Explorer (SELECT_MULTIPLE) oder keiner (SELECT_NONE: Die Tastatur bewegt nur einen Fokus). of_select_node wählt einen Knoten allein aus, öffnet, was ihn enthält, und bringt ihn auf den Bildschirm — ein Baum öffnet, um auszuwählen, wie die TreeView von Windows, aber er prüft zuerst: Ein ausgeblendeter oder in einem ausgeblendeten enthaltener Knoten, einer jenseits der Demogrenze oder einer, den die Suche ausschließt, wird abgelehnt (-5, of_get_last_error sagt warum), und nichts öffnet sich. ue_selection_changed erhält die ausgewählten Adressen als JSON-Array — ob ein Klick, die Tastatur oder Ihr Code sie geändert hat oder ein ausgewählter Knoten den Bildschirm verlassen hat (Zweig geschlossen, Knoten entfernt oder ausgeblendet, Knoten von der Suche verborgen). Das Schließen eines Zweigs bringt den Fokus auf ihn zurück. Mit ib_checkboxes hat jeder Knoten ein Kästchen; mit ib_check_cascade (der Standard) hakt ein Haken des Benutzers an einem Elternknoten dessen Teilbaum an, außer einem ausgegrauten Knoten und seinem Teilbaum, die bleiben, wie sie sind (der Elternknoten ist dann gemischt); ein Haken Ihres Codes hakt alles an. Während einer Suche erfasst die Kaskade den ganzen Teilbaum, verborgene Knoten eingeschlossen. Unter der Kaskade ist ein Elternknoten der Zustand der Kinder, die der Baum zeichnen kann (weder ausgeblendet noch im Demomodus jenseits der Grenze): angehakt, wenn alle es sind, gemischt, wenn ein Teil es ist. Ein vom Benutzer gesetzter Haken löst ue_node_checked aus; ein von Ihrem Code gesetzter Haken (ib_checked, of_check_all) ist ein Wert, stumm wie SetItem. Die unter einem angehakten Blatt empfangenen Kinder übernehmen dessen Haken — alle, die ganze Antwort auf ue_children_needed —, bis ein Haken (Geste oder Code) oder ein hineinverschobener Knoten dem ein Ende setzt. Ein Haken des Benutzers berührt nie einen Knoten jenseits der Demogrenze, mit ib_write_back auch keinen ausgeblendeten. of_select_nodes(as_keys_json) wählt in SELECT_MULTIPLE mehrere Knoten auf einmal aus — das Gegenstück zu of_selected_keys — mit einer einzigen Frage an die Vetos und einem einzigen ue_selection_changed; der Fokus geht auf die zuletzt genannte Adresse.

// Local variables
n_pbt_json lnv_json
string ls_keys[]
long ll_i

// A box before each node : checking a parent checks its subtree
uo_tree.ib_checkboxes = true
uo_tree.of_node(/*keys*/ "europe/france").ib_checked = true

// Every checked node, in the order of the tree
lnv_json.of_load(/*json*/ uo_tree.of_checked_keys())
for ll_i = 1 to lnv_json.of_get_array(/*path*/ "", /*values*/ ls_keys)
    lb_chosen.AddItem(ls_keys[ll_i])
next

Zuerst fragen: Auswahl und Öffnen #

Ein Master-Detail-Bildschirm darf einen nicht gespeicherten Datensatz nicht verlassen. Mit ib_veto_selection erhält ue_selection_changing die aktuelle und die gewünschte Auswahl (JSON-Arrays von Adressen) vor jeder Wahl: ein Klick, Strg- oder Umschalt-Klick, die Tastatur, F3, of_select_node, of_clear_selection, of_search_next oder of_search_prev. Geben Sie FALSE zurück, um abzulehnen: Nichts bewegt sich, nicht einmal der Tastaturfokus, und die Methode gibt -4 zurück; ue_node_clicked wird trotzdem ausgelöst, der Klick hat stattgefunden. Was als Folge die Auswahl verlässt — ein geschlossener Zweig, ein entfernter, ausgeblendeter oder von der Suche verborgener Knoten —, wird nicht gefragt. Ebenso fragt ib_veto_toggle mit ue_node_toggling vor jedem Öffnen oder Schließen, durch eine Geste oder den Code: Ein abgelehntes ib_expanded sendet nichts (of_get_last_error sagt es), of_expand_all, of_collapse_all und of_expand_to_level wenden die übrigen Knoten an und geben -4 zurück, of_select_node und of_scroll_to_node geben -4 zurück, ohne etwas zu öffnen. of_select_node fragt zuerst die Öffnungen (ue_node_toggling), dann die Auswahl: Eine Anwendung handelt nie auf eine angenommene Auswahl, deren Öffnung sie danach ablehnt. Was als Folge die Auswahl verlässt, lässt sich nicht ablehnen: Damit ein geschlossener Zweig keinen nicht gespeicherten Datensatz verlässt, kombinieren Sie ib_veto_selection mit ib_veto_toggle und lehnen das Schließen des Zweigs ab, der ihn enthält. ib_single_expand lässt unter jedem Elternknoten nur einen offenen Zweig: Einen Knoten zu öffnen schließt seine offenen Geschwister, ohne zu fragen; das Setzen schließt im Moment nichts.

// A record shown beside the tree : ask before the selection leaves it, and before
// a branch closes (closing the branch that holds it would leave it)
uo_tree.ib_veto_selection = true
uo_tree.ib_veto_toggle = true
// event ue_selection_changing of uo_tree : (string as_from_keys_json, string as_keys_json)
// Unsaved changes in the detail : the user decides
if dw_detail.ModifiedCount() > 0 then
    if MessageBox("Unsaved changes", "Leave this record without saving?", Question!, YesNo!) = 2 then return false
end if
return true
// event ue_node_toggling of uo_tree : (string as_keys, boolean ab_expanding)
// Closing the branch that holds an unsaved record would leave it : refused
if not ab_expanding and dw_detail.ModifiedCount() > 0 then
    if Pos(uo_tree.of_selected_key() + "/", as_keys + "/") = 1 then return false
end if
return true

Bei Bedarf geladene Zweige #

Ein großer Baum — ein Laufwerk, ein Katalog, eine Tabelle mit Tausenden von Zeilen — muss nicht auf einmal gelesen werden. ib_has_children = true an einem Knoten ist ein Versprechen: Sein Chevron wird angezeigt, obwohl er nichts enthält. Wenn er sich öffnet — ein Klick, die Tastatur, Ihr Code oder of_select_node, das öffnet, was einen Knoten enthält —, wird ue_children_needed ausgelöst: Ihre während des Ereignisses ausgeführten of_add_node sind da, wenn sich der Zweig öffnet, nachdem die Zeile, die ihn geöffnet hat, zurückgekehrt ist (ib_expanded = true wartet nicht auf sie). Das Versprechen gilt bis zu dieser Antwort, auch wenn inzwischen ein Knoten hinzugefügt oder abgelegt wurde; fügen Sie nichts hinzu, wird es zurückgezogen (der Chevron verschwindet). Setzen Sie ib_has_children = true erneut, fragt die nächste Öffnung wieder. Eine während des Ereignisses ausgeführte Öffnung löst nur ein ue_node_toggled aus. of_expand_all öffnet nur die Zweige, die bereits Kinder haben: Ein Zweig, dessen Versprechen nicht beantwortet wurde, bleibt geschlossen, es wird keine Frage in Masse gestellt. Für eine Tabelle muss of_add_node nicht Zeile für Zeile aufgerufen werden: of_from_datastore(ads, as_parent_keys) macht die Zeilen eines DataStores in einer einzigen Nachricht zu Kindern des Knotens — das Muster ItemPopulate → Retrieve der TreeView von PowerBuilder. ROLE_PARENT nennt dort eine Zeile desselben Loses (leer oder unbekannt: direkt unter dem Knoten); derselbe DataStore, erneut unter demselben Knoten übergeben, ersetzt sein Los, ein anderer DataStore fügt seines hinzu. of_row eines Knotens eines Loses liefert seine Zeile in seinem DataStore, und ib_write_back schreibt dorthin. of_clear_children entfernt die Kinder eines Knotens und lässt ihn erneut versprechen: Sein nächstes Öffnen fragt wieder (das „Aktualisieren“ eines Ordners). Geben Sie jedem Los seinen eigenen DataStore (beim Öffnen seines Zweigs erstellt, behalten, solange seine Knoten gezeigt werden): Ein für einen anderen Knoten neu geladener DataStore — Reset, Retrieve, dann of_from_datastore unter einem anderen Knoten — nimmt seine Zeilen zum neuen Los mit, und PowerBuilder vergibt nach einem Reset dieselben RowIDs erneut. Die Knoten des früheren Loses behalten dann, was sie zeigen, haben aber keine Zeile mehr: of_row liefert 0, eine Verschiebung durch den Code liefert -5 („loaded again“), ein umbenannter Text oder ein Haken wird abgelehnt und ue_write_back_failed sagt warum, und das Laden, das es verursacht hat, zählt sie (stale=N) in of_get_last_error. Derselbe DataStore, erneut unter demselben Knoten übergeben, ersetzt sein Los; um ein Los aus einem anderen DataStore-Objekt aufzufrischen, rufen Sie zuerst of_clear_children auf, sonst wird es neben das erste gestellt. Eine Spalte namens has_children (ROLE_HAS_CHILDREN) lässt eine Zeile eigene Kinder versprechen, ohne Schleife. Ein leeres as_parent_keys wird abgelehnt (-5): Die Spitze des Baums ist of_from_datastore(ads).

// A folder that promises children : nothing is read before it opens
uo_tree.of_add_node(/*keys*/ "docs", /*text*/ "Documents", /*image*/ "img\packimages.dll:png/folder")
uo_tree.of_node(/*keys*/ "docs").is_expanded_image = "mono:img\packimages.dll:svg/samples/folder-open"
uo_tree.of_node(/*keys*/ "docs").ib_has_children = true
// event ue_children_needed of uo_tree : (string as_keys)
// Local variables
datastore lds_folders
n_pbt_utils lnv_utils

// The folder opens : ITS sub-folders are retrieved into a DataStore of their own and
// added in ONE call - code is their key and name their text (of_map, once), the
// column has_children says whether each one promises its own
lds_folders = create datastore
lds_folders.DataObject = "d_folders"
lds_folders.SetTransObject(SQLCA)

// as_keys is the whole ADDRESS (docs/reports) : the code of the folder is its LAST key
lds_folders.Retrieve(lnv_utils.of_leaf(/*keys*/ as_keys))
uo_tree.of_from_datastore(/*ads*/ lds_folders, /*parent_keys*/ as_keys)

// One DataStore per lot, kept while its nodes are shown : of_row and ib_write_back
// read it ; the window destroys them when it closes
ids_lots[UpperBound(ids_lots) + 1] = lds_folders

Umbenennen und verschieben #

Mit ib_editable benennt der Benutzer einen Knoten um: F2 oder ein Klick auf den bereits ausgewählten Knoten (nach einer kurzen Verzögerung, wie im Explorer). Eingabe (oder das Verlassen des Feldes) behält den Text, Esc stellt ihn wieder her, ein geleerter Text wird abgelehnt (die Bearbeitung wird abgebrochen); ue_node_edited erhält den getippten Text und den alten — ein getippter Text ist Text, niemals Auszeichnung. Ein Befehl Ihres Codes während der Bearbeitung behält das Feld und das darin Getippte; verlässt die bearbeitete Zeile den Bildschirm ohne Geste des Benutzers (Code, Bildlauf), wird die Bearbeitung abgebrochen. Mit ib_drag_drop zieht er einen Knoten: auf dem oberen Viertel einer Zeile kommt er vor sie, auf dem unteren Viertel hinter sie — als erstes Kind, wenn sie ein offener Zweig ist —, in der Mitte in sie; ein geschlossener Zweig unter dem Zeiger öffnet sich nach einem Moment, der Baum rollt nahe an seinen Rändern, Esc bricht ab, ein Knoten kommt nie in seinen eigenen Teilbaum noch dorthin, wo sein Schlüssel vergeben ist, und auf der Zeile eines ausgegrauten Knotens wird nichts abgelegt. Ein Ziehen, dessen losgelassene Taste der Baum nicht sieht — das Fenster verliert den Fokus (Alt+Tab, ein Meldungsfenster) —, wird abgebrochen: Nichts bewegt sich. Unter einer Sortierung oder mit ib_parents_first geht ein Ablegen nur hinein. ue_node_moved erhält die neue Adresse, die alte und den Platz unter dem neuen Elternknoten; ein an seinem Platz abgelegter Knoten fragt, schreibt und löst nichts aus. Mit ib_veto_changes werden ue_node_editing und ue_node_moving vorher gefragt — ue_node_moving mit dem endgültigen Platz, dem, den ue_node_moved nennen wird: Geben Sie FALSE zurück, um abzulehnen — nichts ändert sich, und of_move_node gibt -4 zurück. Es wird jeweils ein Knoten gezogen, auch bei Mehrfachauswahl.

// Renaming and moving by the user, with a question before each change
uo_tree.ib_editable = true
uo_tree.ib_drag_drop = true
uo_tree.ib_veto_changes = true
// event ue_node_moving of uo_tree : (string as_keys, string as_to_parent_keys, long al_position)
// Nothing goes to the top level : FALSE keeps the node where it is
if as_to_parent_keys = "" then return false
return true

Auch Ihr Code öffnet einen Namen zur Bearbeitung: of_edit_node(as_keys) — das EditLabel eines PowerBuilder-TreeView, für einen „Neuen Ordner“, der sich bereit zur Benennung öffnet. Der Knoten wird zuerst ausgewählt (was ihn enthält, öffnet sich), dann öffnet sich das Feld; das Ende gehört dem Benutzer, wie oben. Eine Sperre hält den Benutzer auf, nie Ihren Code: Es funktioniert mit ib_editable = false, auf einem schreibgeschützten oder ausgegrauten Knoten. of_cancel_edit() schließt das Feld und stellt den Text wieder her, wie Esc.

// A new folder, opened at once in edit mode : the user types its name, then Enter
uo_tree.of_add_node(/*keys*/ "docs/new", /*text*/ "New folder")
uo_tree.of_edit_node(/*keys*/ "docs/new")

Sperren, Entf und Kopieren #

Drei Sperren pro Knoten halten den Benutzer auf, nie Ihren Code: ib_read_only (weder umbenannt noch gezogen, er bleibt ein Ziel), ib_drop_target = false (nichts wird in ihn abgelegt, weder ein Knoten noch eine Datei — davor oder dahinter bleibt erlaubt) und ib_show_checkbox = false (kein Kästchen: Der Knoten zählt nicht für seinen Elternknoten, steht nicht in of_checked_keys, und die Kaskade geht durch ihn hindurch zu seinen Kindern). Entf löst ue_delete_requested mit den ausgewählten Knoten aus (in SELECT_NONE dem mit dem Fokus; ohne Auswahl sonst wird nichts ausgelöst), außer ausgegrauten und schreibgeschützten: Der Baum entfernt nichts, Ihre Anwendung ruft of_remove_node für das auf, was sie löscht. Strg+C (oder Strg+Einfg) löst ue_copy mit den ausgewählten Knoten (in SELECT_NONE dem mit dem Fokus) als tabulatorgetrenntem Text aus, eine Zahl roh (ein Punkt, weder Gruppierung noch Symbol): der Text nach so vielen Tabulatoren wie seine Tiefe, dann die Spalten einer Baumliste ausgerichtet, zuerst eine Kopfzeile; der Baum versucht auch die Zwischenablage des Browsers, die der Seite verweigert werden kann — ClipBoard(as_tsv), um sicher zu sein.

// The system folder : neither renamed nor dragged, nothing dropped into it, no check box
uo_tree.of_node(/*keys*/ "system").ib_read_only = true
uo_tree.of_node(/*keys*/ "system").ib_drop_target = false
uo_tree.of_node(/*keys*/ "system").ib_show_checkbox = false
// event ue_delete_requested of uo_tree : (string as_keys_json)
// Local variables
n_pbt_json lnv_json
string ls_keys[]
long ll_i

// Delete pressed : the tree removes nothing, your application decides
lnv_json.of_load(/*json*/ as_keys_json)
for ll_i = 1 to lnv_json.of_get_array(/*path*/ "", /*values*/ ls_keys)
    uo_tree.of_remove_node(/*keys*/ ls_keys[ll_i])
next
// event ue_copy of uo_tree : (string as_tsv)
// Ctrl+C : the nodes copied, ready for a spreadsheet
ClipBoard(as_tsv)

Aus dem Explorer abgelegte Dateien #

Mit ib_allow_drop nimmt der Baum Dateien an, die aus dem Windows-Explorer auf einen Knoten gezogen werden: Der Knoten unter dem Cursor leuchtet während des Ziehens auf, ue_drop_files erhält seine Adresse und die vollständigen Pfade. as_keys ist leer bei einem Ablegen neben den Knoten, auf einem ausgegrauten Knoten oder auf einem Knoten, dessen ib_drop_target false ist. ue_drag_enter und ue_drag_leave melden, dass ein Ziehen von Dateien hereingekommen und wieder gegangen ist, ohne abzulegen.

// Files of the Explorer dropped on a folder of the tree
uo_tree.ib_allow_drop = true
// event ue_drop_files of uo_tree : (string as_keys, string as_files[])
// The folder under the cursor : your application copies the files there
if as_keys <> "" then wf_copy_files(as_files, uo_tree.of_get_field(/*keys*/ as_keys, /*field*/ "path"))

Spalten, Sortierung und Layout #

of_add_column macht aus dem Baum eine Baumliste: Die erste Spalte trägt den Baum (ihr Titel ist is_tree_title), jede hinzugefügte Spalte zeigt das Feld mit demselben Schlüssel jedes Knotens — gesetzt über of_set_field oder eine Spalte des DataStores. Der Handle einer Spalte (of_column) legt ihren Titel, ihre Breite (0 = automatisch), ihre Ausrichtung, ihr Format (eine Zahlenmaske wie "#,##0.00" mit den Trennzeichen der Anzeigesprache oder Datums-Token für einen Wert "yyyy-mm-dd", die des datagrid), ihre Sichtbarkeit und ihren Platz fest. Ein Klick auf eine Kopfzeile sortiert die Geschwister jeder Ebene — aufsteigend, absteigend, dann die Reihenfolge des Hinzufügens — und löst ue_sort_changed aus; of_sort tut dasselbe per Code. Die Sortierung ändert nur die angezeigte Reihenfolge: of_keys_at und die Positionen behalten die Reihenfolge des Hinzufügens. Der Benutzer verbreitert eine Spalte über den Rand ihrer Kopfzeile und verschiebt sie durch Ziehen der Kopfzeile. Was er angeordnet hat — Breiten, Reihenfolge, Sichtbarkeit, Sortierung, offene Knoten —, wird über of_get_layout gelesen und über of_set_layout zurückgegeben; ue_layout_changed trägt das ganze Layout nach jeder Geste, die es ändert, und wenn Ihr Code die Breite, den Platz oder die Sichtbarkeit einer Spalte schreibt (ii_width, ii_index, ib_visible) und sich das Layout ändert. Gleiche Werte behalten die Reihenfolge des Modells, und die Sortierung wird neu ausgeführt, wenn sich die Anzeigesprache ändert. Das Entfernen der sortierten Spalte (of_remove_column, of_clear_columns) löst ue_sort_changed mit dem nächsten Schlüssel der Sortierung aus — SORT_NONE, wenn es der einzige war —, dann ue_layout_changed. Die fünf Farben des Handles einer Spalte (il_accent, il_back_color, il_text_color, il_back_color_hover, il_text_color_hover) färben ihre Kopfzeile. Sobald es Spalten gibt, bleibt die Baumspalte beim waagerechten Bildlauf fixiert. Die Sortierung kann mehrere Schlüssel haben: of_sort(as_sort) liest die Syntax des SetSort eines DataWindows („type A, text D“, wobei „text“ der Text der Knoten ist), of_sort(as_column, as_dir) nimmt auch ein Feld an, das keine Spalte zeigt, und ue_sort_changed erhält die ganze Sortierung als drittes Argument. ib_parents_first stellt auf jeder Ebene die Knoten, die Kinder haben (oder versprechen), vor die Blätter — die Ordner vor die Dateien —, welche Sortierung auch immer. Eine Spalte kann den Schlüssel text nicht nehmen, der den Text der Knoten bezeichnet (-5): of_sort("text", as_dir) sortiert danach, und of_sort akzeptiert mehrere Leerzeichen zwischen einer Spalte und ihrer Richtung, wie SetSort.

// A tree list : the population of each country beside the tree
uo_tree.is_tree_title = "Country"
uo_tree.of_add_column(/*key*/ "population", /*title*/ "Population", /*width*/ 120)
uo_tree.of_column(/*key*/ "population").is_format = "#,##0"
uo_tree.of_column(/*key*/ "population").is_align = u_pbt_treeview.ALIGN_END
uo_tree.of_set_field(/*keys*/ "europe/france", /*field*/ "population", /*value*/ "68000000")

// The largest countries first, inside each continent
uo_tree.of_sort(/*column*/ "population", /*dir*/ u_pbt_treeview.SORT_DESC)
// The folders first, then by type and by name
uo_tree.ib_parents_first = true
uo_tree.of_sort(/*sort*/ "type A, text A")

Den Baum mit seiner Hierarchie exportieren: of_export_csv(as_path) schreibt eine CSV-Datei (UTF-8, Semikolon), in der der Text eines Knotens in der Zelle seiner Ebene steht — eine Zelle weiter rechts pro Ebene —, die Spalten einer Baumliste nach der tiefsten Ebene, zuerst eine Kopfzeile; of_export_xlsx(as_path) schreibt eine Excel-Arbeitsmappe, in der der Text um seine Ebene eingerückt und jeder Zweig unter seinem Elternknoten gruppiert ist, in Excel einklappbar, und Zahlen Zahlen bleiben. is_export_scope sagt, welche Knoten: EXPORT_ALL (Standard) alle Knoten, geschlossene Zweige eingeschlossen, EXPORT_SHOWN die Zeilen auf dem Bildschirm. Der Baum erstellt die Datei, die DLL schreibt sie, ue_csv_saved / ue_xlsx_saved bestätigen; im Demomodus abgelehnt.

// The tree written to Excel - every node, the closed branches too ; ue_xlsx_saved confirms
uo_tree.is_export_scope = u_pbt_treeview.EXPORT_ALL
uo_tree.of_export_xlsx(/*path*/ "C:\exports\countries.xlsx")

Gesamtwerte pro Zweig #

Eine Spalte einer Baumliste kann an jedem Zweig den Gesamtwert dessen zeigen, was er enthält: is_summary an ihrem Handle ist SUMMARY_SUM, SUMMARY_AVG, SUMMARY_MIN, SUMMARY_MAX oder SUMMARY_COUNT (die nicht leeren Werte). Die Berechnung geht bis zu den Blättern hinunter — ein Durchschnitt ist der der Blätter, nie ein Durchschnitt von Durchschnitten —, und der Gesamtwert wird fett über is_format geschrieben — eine Anzahl immer als einfache Zahl. Ein Zweig mit eigenem Wert behält ihn und gibt ihn nach oben weiter, außer mit ib_summary_over_value an der Spalte. Es zählen nur die Knoten, die der Baum zeichnen kann (nie ein ausgeblendeter); mit ib_summary_filtered an der Komponente nur, was die Suche zeigt. of_get_field liefert den rohen Gesamtwert (eine Zahl mit Punkt), eine Sortierung nach dieser Spalte verwendet die Gesamtwerte, und die Gesamtwerte folgen jedem Hinzufügen, Entfernen oder Ziehen. SUMMARY_MIN und SUMMARY_MAX vergleichen auch Datumswerte (yyyy-mm-dd, yyyy-mm-dd hh:mm:ss, hh:mm:ss), und eine Summe ganzer Zahlen bleibt über 2^53 hinaus exakt.

// Each continent shows the sum of its countries, in bold
uo_tree.of_column(/*key*/ "population").is_summary = u_pbt_treeview.SUMMARY_SUM

// The total of Europe, read like a field
st_total.text = uo_tree.of_get_field(/*keys*/ "europe", /*field*/ "population")

Suchen #

is_filter zeigt nur die Knoten, deren Text die Suche enthält (Groß-/Kleinschreibung ignoriert), mit den Knoten, die sie enthalten, geöffnet, und dem gefundenen Text hervorgehoben. "" zeigt alles. Was einen Treffer enthält, wird geöffnet angezeigt, ohne ib_expanded zu ändern, und die Chevrons sind während der Suche wirkungslos. Mit ib_toolbar trägt eine Leiste über dem Baum ein Suchfeld (das is_filter schreibt: Ein Lesen liefert es sofort) und die Schaltflächen Alle aufklappen und Alle zuklappen. Esc im Feld leert die Suche, Pfeil nach unten wechselt zum Baum, Eingabe und F3 gehen zum nächsten Treffer (Umschalt: zum vorigen), und das Feld behält die Tastatur. Ein ausgewählter Knoten, den die Suche verbirgt, verlässt die Auswahl, und ue_selection_changed meldet es; der Knoten, der ihn enthält, wird nicht an seiner Stelle ausgewählt. of_select_node und of_scroll_to_node lehnen einen Knoten ab, den die Suche ausschließt (-5). Um von Treffer zu Treffer zu gehen, wählen of_search_next und of_search_prev den nächsten oder vorigen nach dem Knoten mit dem Fokus aus, im Kreis (F3 und Umschalt+F3 über die Tastatur), und of_match_count sagt, wie viele die Suche gefunden hat. of_find_node(as_field, as_value, as_after_keys) findet ohne zu filtern: die Adresse des ersten Knotens, dessen Feld ("" = sein Text) genau den Wert enthält, in der Reihenfolge, die der Baum zeigt, geschlossene Zweige eingeschlossen; übergeben Sie die gefundene Adresse erneut für den nächsten. In SELECT_NONE bewegen of_search_next und of_search_prev den Fokus dorthin, wie F3. of_find_node beginnt nach dem Platz von as_after_keys in der angezeigten Reihenfolge — auch bei einem ausgeblendeten Knoten; ein unbekannter liefert "", und of_get_last_error sagt es. of_find_nodes(as_field, as_value) liefert alle Treffer auf einmal, als JSON-Array in der angezeigten Reihenfolge.

Die Suche ignoriert Akzente standardmäßig, wie die Sortierung: „montreal“ findet „Montréal“, und das türkische I mit Punkt zählt als I („izmir“ findet „İzmir“); ib_filter_accents = true lässt sie zählen. Bei Mehrfachauswahl wählt Strg+A alle angezeigten Knoten aus (eine einzige Frage mit ib_veto_selection).

// A search field above the tree, and a first search from the code
uo_tree.ib_toolbar = true
uo_tree.is_filter = "par"
// Local variables
string ls_keys

// The first node whose code is FR, selected if there is one
ls_keys = uo_tree.of_find_node(/*field*/ "code", /*value*/ "FR", /*after_keys*/ "")
if ls_keys <> "" then uo_tree.of_select_node(/*keys*/ ls_keys)
// Every node whose status is late, selected at once (a multiple selection)
uo_tree.is_selection_mode = u_pbt_treeview.SELECT_MULTIPLE
uo_tree.of_select_nodes(/*keys_json*/ uo_tree.of_find_nodes(/*field*/ "status", /*value*/ "late"))

Aus einem DataStore #

of_from_datastore macht aus jeder Zeile einer hierarchischen Tabelle einen Knoten: Die Spalte ROLE_KEY gibt seinen Schlüssel (ohne sie die RowID der Zeile), die Spalte ROLE_PARENT nennt den Schlüssel des Knotens, der ihn enthält (leer, unbekannt oder eine Schleife: ganz oben) — mit einer Spalte ROLE_KEY nennt ein Elternwert einen Schlüssel, niemals eine RowID. Die anderen Rollen: der Text (ROLE_TEXT, als Text angezeigt, nie als Auszeichnung), das Bild, der Haken, das Badge und ob er beim Laden offen ist. Eine Spalte spielt eine Rolle, wenn sie so heißt (key, parent, text…) oder wenn of_map es sagt. Jede Spalte ist ein Feld (of_get_field) — die Spalten der Liste werden nicht für Sie angelegt: of_add_column mit dem Spaltennamen. Datums- und Zahlenwerte werden unabhängig von den Regionaleinstellungen in einer einzigen Form gelesen: ein Datum yyyy-mm-dd, ein Datum mit Uhrzeit yyyy-mm-dd hh:mm:ss, eine Zahl mit Punkt und ohne überflüssige Null (1234,50 wird 1234.5) — eine Dezimalspalte wird als Zahl formatiert und sortiert. Zwei Zeilen mit demselben Schlüssel: Die zweite erhält "Schlüssel~RowID". Was das Laden korrigieren musste (Zeilen, deren Elternknoten fehlt, aufgebrochene Schleifen, doppelte Schlüssel, unmögliche Schlüssel), sagt of_get_last_error, die Rückgabe bleibt 0. of_reload_row liest eine von Ihrem Code geänderte Zeile erneut und aktualisiert ihren Knoten an Ort und Stelle; eine Zeile, deren Schlüssel oder Elternknoten sich geändert hat, verschiebt ihren Knoten. Der Knoten einer Zeile, der durch of_remove_node entfernt wurde, bleibt bis zum nächsten of_from_datastore weg; of_reload_row seiner Zeile bringt ihn zurück. Mit ib_write_back wird ein umbenannter Text in die Spalte ROLE_TEXT geschrieben, und ein Knoten, der den Elternknoten wechselt, schreibt ihn in die Spalte ROLE_PARENT (NULL ganz oben, welcher Typ auch immer; eine Verschiebung unter denselben Geschwistern schreibt nichts), vor dem Ereignis; ein Knoten einer Zeile geht dann weder unter einen von Hand hinzugefügten Knoten noch unter eine Zeile ohne Schlüsselwert — seine Elternspalte könnte es nicht ausdrücken. Ein Wert, den der DataStore ablehnt, oder ein seit dem Laden zerstörter DataStore (no DataStore is bound) setzt den Knoten zurück und löst ue_write_back_failed aus. Ohne ib_write_back verschiebt ein Ziehen nur den Knoten: Seine Zeile behält, was der DataStore sagt, und das nächste Lesen der Zeilen (of_map, is_group_by, of_reload_row, ein neues Laden) setzt den Knoten dorthin zurück, wo seine Zeile es sagt — sein altes Handle wird freigegeben. Das Update bleibt Ihre Sache. Der Handle eines Knotens liest die Nummer seiner Zeile (of_row). of_from_datastore liest auch die Zeilen eines DataWindows oder eines DataWindowChilds — dessen, das der Benutzer daneben sieht: Der Baum schreibt dann in dieses. Mit ib_write_back wird ein Haken des Benutzers auch in die Spalte ROLE_CHECKED jeder Zeile geschrieben, die er geändert hat — die Kaskade eingeschlossen, und die Zweige darüber, deren Zustand zu angehakt oder nicht angehakt wechselt (ein Zweig, der gemischt wird, behält seinen Wert) —, so geschrieben, wie die Spalte es bereits tut (1/0, Y/N, T/F, O/N, -1/0…; eine Spalte, die nur ihr Nein zeigt, schreibt das übliche Ja: Y für N, 1 für 0 — O und -1 nur, wenn die Spalte schon eines enthält); eine Spalte, deren Werte weder ein Ja noch ein Nein sind, wird mit ihrem Grund abgelehnt. Jeder Wert wird zuerst geprüft, und das Schreiben ist alles oder nichts: Eine Ablehnung gibt die Haken der Geste zurück und löst ue_write_back_failed aus. of_row_keys liefert die Adresse des Knotens einer Zeile des Haupt-DataStores: Entfernen Sie den Knoten vor einem DeleteRow. Jedes Zurückschreiben ist alles oder nichts — jeder Wert wird geprüft, bevor einer geschrieben wird; ein Datum mit Uhrzeit behält seine Uhrzeit, eine time-Spalte wird als hh:mm:ss geschrieben, gelesen und gruppiert. Eine von of_move_node geschriebene Verschiebung wird nach ue_node_moving erneut geprüft, und das Geschriebene wird zurückgesetzt, wenn sich der Knoten nicht bewegt. Mit ib_write_back lässt sich ein Knoten einer Zeile, deren DataStore keine ROLE_TEXT-Spalte hat, nicht umbenennen. Ein neues Laden gibt nur die Handles dessen frei, was es ersetzt: das Handle eines von Hand hinzugefügten Knotens, ein inaktives Handle oder eines, das für eine noch nicht erstellte Adresse genommen wurde, bleiben gültig; of_from_datastore aus einer DataWindow prüft, dass ihre Daten geteilt werden können (-5 mit dem Grund). Was ein Lesen der Zeilen korrigieren musste, wird in of_get_last_error gezählt — auch die von Hand hinzugefügten Knoten, die an die Spitze gehoben wurden, weil ihre Gruppe weg ist (lifted=N), und die Lose, die mit ihrem Knoten gegangen sind (lots=N); of_map und is_group_by melden es für alle Quellen.

// The departments : each row names its parent by its id
ids_depts.Retrieve()
uo_tree.of_map(/*role*/ u_pbt_treeview.ROLE_KEY, /*column*/ "dept_id")
uo_tree.of_map(/*role*/ u_pbt_treeview.ROLE_PARENT, /*column*/ "parent_id")
uo_tree.of_map(/*role*/ u_pbt_treeview.ROLE_TEXT, /*column*/ "dept_name")
uo_tree.of_from_datastore(/*ads*/ ids_depts)

// Two columns of the DataStore shown beside the tree
uo_tree.of_add_column(/*key*/ "head_count", /*title*/ "Staff")
uo_tree.of_add_column(/*key*/ "budget", /*title*/ "Budget")
uo_tree.of_column(/*key*/ "budget").is_format = "#,##0"

// A renamed or moved department is written into its row before the event
uo_tree.ib_write_back = true
uo_tree.ib_editable = true
uo_tree.ib_drag_drop = true
// event ue_node_moved of uo_tree : (string as_keys, string as_old_keys, long al_position)
// parent_id is already written in the row : save it
if ids_depts.Update() = 1 then commit using sqlca;

Eine Rolle wird pro DataStore aufgelöst: die Spalte, die of_map(ads, as_role, as_column) diesem DataStore gegeben hat, sonst die von of_map(as_role, as_column), wenn dieser DataStore sie hat, sonst die nach der Rolle benannte Spalte. Ein Los von Mitarbeitern unter einem Baum von Abteilungen braucht also keine der Spalten der Abteilungen. Eine Tabelle, deren Wurzeln 0 in ihrer Elternspalte tragen (eine NOT-NULL-Spalte), sagt es mit is_root_parent_value = "0" ("0|-1" für zwei Werte): Diese Zeilen stehen oben, ohne als verwaist zu zählen, und ein mit ib_write_back nach oben verschobener Knoten schreibt 0 statt NULL. Die Spalten ROLE_STATE_IMAGE und ROLE_OVERLAY_IMAGE geben das Statusbild und das überlagerte Bild eines Knotens, gelesen wie ROLE_IMAGE.

// event ue_children_needed of uo_tree : (string as_keys)
// Local variables
datastore lds_staff
n_pbt_utils lnv_utils

// The employees of the department that opens, in a DataStore of their own
lds_staff = create datastore
lds_staff.DataObject = "d_staff"
lds_staff.SetTransObject(SQLCA)
lds_staff.Retrieve(lnv_utils.of_leaf(/*keys*/ as_keys))

// THEIR key and THEIR text : the departments keep dept_id and dept_name
uo_tree.of_map(/*ads*/ lds_staff, /*role*/ u_pbt_treeview.ROLE_KEY, /*column*/ "emp_id")
uo_tree.of_map(/*ads*/ lds_staff, /*role*/ u_pbt_treeview.ROLE_TEXT, /*column*/ "emp_name")
uo_tree.of_from_datastore(/*ads*/ lds_staff, /*parent_keys*/ as_keys)

// Kept while its nodes are shown ; the window destroys them when it closes
ids_lots[UpperBound(ids_lots) + 1] = lds_staff
// The roots of the table carry 0 in parent_id (a NOT NULL column) : 0 names the top
uo_tree.is_root_parent_value = "0"
uo_tree.of_from_datastore(/*ads*/ ids_depts)

Ein nach Spalten gruppierter Baum #

Der TreeView-Stil eines DataWindows, ohne DataWindow: is_group_by = "region|country|city" macht die Zeilen von of_from_datastore zu Blättern von Gruppen, die auf den Werten dieser Spalten aufbauen, eine Ebene pro Spalte (ROLE_PARENT spielt keine Rolle, ROLE_KEY benennt die Blätter). Der Schlüssel einer Gruppe ist ihr Wert (/, | und % als %2F, %7C, %25 geschrieben), ihr Text der Wert im Format der gleichnamigen Spalte, „(leer)“ für einen leeren Wert; der Handle eines Gruppenknotens liest of_group_column() und of_group_value(). Nach einem Laden gesetzt, gruppiert es neu; of_reload_row ordnet eine Zeile, deren Wert sich geändert hat, in ihre neue Gruppe ein. of_set_level_image gibt allen Knoten einer Ebene ein Bild, of_expand_to_level öffnet den Baum bis zu einer Ebene, und is_summary gibt die Gesamtwerte jeder Gruppe. Mit ib_write_back schreibt ein Blatt, das unter einer Gruppe der letzten Ebene abgelegt wird, vor dem Ereignis alle seine Gruppenspalten; anderswo und für einen Gruppenknoten wird das Verschieben abgelehnt. Der Text einer Gruppe folgt einem nach dem Laden gesetzten Format, dem Eintreffen ihrer Spalte und der Anzeigesprache; ein Wert, der mit __ beginnt, wird im Schlüssel %5F_ geschrieben; of_group_value eines Datums mit Uhrzeit ist yyyy-mm-dd hh:mm:ss, einer Uhrzeit hh:mm:ss. Ohne ib_write_back kehrt ein unter eine andere Gruppe gezogenes Blatt beim nächsten Gruppieren in seine eigene zurück, da sich seine Zeile nicht geändert hat; ein von Hand hinzugefügter Knoten unter einer verschwindenden Gruppe steigt an die Spitze.

// The sales, one row per sale, grouped by region, country and city : the customer is
// the text of each sale
uo_tree.is_group_by = "region|country|city"
uo_tree.of_map(/*role*/ u_pbt_treeview.ROLE_TEXT, /*column*/ "customer")
uo_tree.of_from_datastore(/*ads*/ ids_sales)

// The amount of each sale, and the total of each group
uo_tree.of_add_column(/*key*/ "amount", /*title*/ "Amount")
uo_tree.of_column(/*key*/ "amount").is_format = "#,##0.00"
uo_tree.of_column(/*key*/ "amount").is_summary = u_pbt_treeview.SUMMARY_SUM

// A globe before every region ; only the regions show at first
uo_tree.of_set_level_image(/*level*/ 1, /*image*/ "mono:img\packimages.dll:svg/ribbon/globe", /*expanded_image*/ "")
uo_tree.of_expand_to_level(/*level*/ 1)

Eigenschaften #

EigenschaftTypStandardZweck
is_selection_modestringSELECT_SINGLEWie der Benutzer auswählt: SELECT_SINGLE (ein Knoten), SELECT_MULTIPLE (Strg und Umschalt, wie im Explorer) oder SELECT_NONE (die Tastatur bewegt nur einen Fokus, nichts wird ausgewählt). Ein anderer Wert wird abgelehnt: der alte bleibt, of_get_last_error sagt warum
ib_checkboxesbooleanfalseEin Kontrollkästchen vor jedem Knoten
ib_check_cascadebooleantrueEin Haken des Benutzers an einem Knoten hakt seinen Teilbaum an, außer einem ausgegrauten Knoten und seinem Teilbaum; ein Haken des Codes hakt alles an. Ein Elternknoten ist der Zustand der Kinder, die der Baum zeichnen kann: angehakt, wenn alle es sind, gemischt (CHECK_MIXED), wenn ein Teil es ist. false: Jeder Knoten behält seinen eigenen Haken; ein Haken des Benutzers berührt nie einen Knoten jenseits der Demogrenze, mit ib_write_back auch keinen ausgeblendeten
ib_editablebooleanfalseDer Benutzer benennt einen Knoten um: F2 oder ein Klick auf den bereits ausgewählten Knoten. Eingabe behält, Esc stellt wieder her (ue_node_edited); ein geleerter Text wird abgelehnt
ib_drag_dropbooleanfalseDer Benutzer zieht einen Knoten vor, hinter oder in einen anderen (ue_node_moved); nie in seinen eigenen Teilbaum; ein Ablegen auf dem unteren Viertel eines offenen Zweigs macht ihn zu dessen erstem Kind; verliert das Fenster während des Ziehens den Fokus, wird es abgebrochen
ib_veto_changesbooleanfalseue_node_editing und ue_node_moving vorher fragen, bevor ein getippter Text behalten oder ein Knoten verschoben wird — per Geste wie per of_move_node (standardmäßig aus, wie jedes abbrechbare Ereignis)
is_filterstring""Die Suche: Nur die Knoten, deren Text sie enthält, werden angezeigt, mit denen, die sie enthalten, geöffnet, der gefundene Text hervorgehoben. "" zeigt alles. Das Feld der Symbolleiste schreibt sie auch: Ein Lesen liefert sie sofort; ein ausgewählter Knoten, den sie verbirgt, verlässt die Auswahl (ue_selection_changed)
ib_toolbarbooleanfalseEine Leiste über dem Baum: das Suchfeld, Alle aufklappen, Alle zuklappen
ib_show_linesbooleanfalseDünne Linien verbinden jeden Knoten mit seinem Elternknoten
ii_indentinteger18Der Einzug einer Ebene, in Pixeln, von 8 bis 64. Ein anderer Wert wird abgelehnt: der alte bleibt, of_get_last_error sagt warum
is_tree_titlestring""Der Titel der Baumspalte einer Baumliste. Akzeptiert die Rich-Text-Auszeichnung
ib_write_backbooleanfalseMit einem über of_from_datastore gespeisten Baum: Ein umbenannter Text wird in die Spalte ROLE_TEXT geschrieben, ein Knoten, der den Elternknoten wechselt, schreibt ihn in die Spalte ROLE_PARENT (NULL ganz oben; eine Verschiebung unter denselben Geschwistern schreibt nichts), vor dem Ereignis. Ein Knoten einer Zeile geht dann weder unter einen von Hand hinzugefügten Knoten noch unter eine Zeile ohne Schlüsselwert. Ein abgelehnter Wert oder ein zerstörter DataStore setzt den Knoten zurück und löst ue_write_back_failed aus. Ohne diese Option verschiebt ein Ziehen nur den Knoten. Das Update bleibt Ihre Sache. Ein Haken des Benutzers wird auch in die Spalte ROLE_CHECKED jeder Zeile geschrieben, die er ändert. Ein Haken schreibt auch die Zweige darüber, deren Zustand zu angehakt oder nicht angehakt wechselt; jeder Wert wird zuerst geprüft, alles oder nichts; ohne ROLE_TEXT-Spalte lässt sich ein Knoten einer Zeile nicht umbenennen
ib_enabledbooleantruefalse graut den Baum aus: Die Knoten bleiben sichtbar, nichts reagiert mehr auf den Benutzer, und der Baum verlässt die Tabulatorreihenfolge. Ihr Code ändert weiterhin alles; er nimmt keinen Fokus mehr an
ib_veto_selectionbooleanfalseue_selection_changing vor einer Änderung der Auswahl fragen: eine Wahl des Benutzers, of_select_node, of_clear_selection (standardmäßig aus, wie jedes abbrechbare Ereignis)
ib_veto_togglebooleanfalseue_node_toggling vor dem Öffnen oder Schließen eines Knotens fragen, durch eine Geste oder den Code
ib_single_expandbooleanfalseEin offener Zweig unter jedem Elternknoten: Einen Knoten zu öffnen schließt seine offenen Geschwister (ue_node_toggled für jeden, ohne Frage); das Setzen schließt im Moment nichts; of_expand_all und of_expand_to_level ignorieren es
ib_parents_firstbooleanfalseAuf jeder Ebene die Knoten mit (oder mit versprochenen) Kindern vor den Blättern — die Ordner vor den Dateien —, welche Sortierung auch immer; ein Ablegen geht dann nur hinein
ib_summary_filteredbooleanfalseDie Gesamtwerte der Zweige (is_summary einer Spalte) zählen nur, was die Suche zeigt; false: jeden Knoten, den der Baum zeichnen kann
is_group_bystring""Ein nach Spalten gruppierter Baum, wie der TreeView-Stil eines DataWindows: `"regioncountry" macht eine Gruppenebene pro Spalte, die Zeilen von of_from_datastore sind die Blätter unter der letzten. Nach einem Laden gesetzt, gruppiert es neu; eine Spalte, die der DataStore nicht hat, wird ignoriert. Was ein Gruppieren für alle Quellen korrigieren musste, liest sich in of_get_last_error`
is_root_parent_valuestring""Die Elternwerte, die die Spitze des Baums benennen, verbunden durch ` ("0", "0-1"): Eine solche Zeile steht oben, ohne als verwaist zu zählen, und ein mit ib_write_back nach oben verschobener Knoten schreibt den ersten statt NULL. ""`: nur ein leerer (NULL) Elternwert benennt die Spitze
ib_filter_accentsbooleanfalsefalse: Die Suche (is_filter) ignoriert Akzente, wie die Sortierung; true: sie zählen
ib_auto_tooltipbooleantrueEine durch die Breite abgeschnittene Beschriftung zeigt ihren ganzen Text in einem Tooltip — nie über einem Tooltip, den Ihre Anwendung dem Knoten gegeben hat
is_export_scopestringEXPORT_ALLWas of_export_csv und of_export_xlsx schreiben: EXPORT_ALL alle Knoten, geschlossene Zweige eingeschlossen, EXPORT_SHOWN die Zeilen auf dem Bildschirm. Ein ausgeblendeter Knoten wird nie geschrieben; ein anderer Wert wird abgelehnt
ib_allow_dropbooleanfalseAus dem Explorer auf einen Knoten abgelegte Dateien annehmen: Der Knoten unter dem Cursor leuchtet auf, ue_drop_files nennt ihn mit den vollständigen Pfaden
is_theme_stylestring""Visueller Stil der Komponente (Konstanten THEME_STYLE_*); leer = der der Anwendung, bei jeder Änderung übernommen
is_theme_modestring""Helle oder dunkle Variante (Konstanten THEME_MODE_*); leer = die der Anwendung, bei jeder Änderung übernommen
il_theme_accentlong-1Akzentfarbe dieser Komponente (-1 = Akzent der Anwendung, sonst der des Designs)
is_tooltipstring""Einfacher Tooltip beim Überfahren der Komponente
is_super_tooltip_titlestring""Titel des erweiterten Tooltips (hat Vorrang vor is_tooltip)
is_super_tooltip_textstring""Text des erweiterten Tooltips (Rich-Markup zulässig)
is_super_tooltip_imagestring""Bild des erweiterten Tooltips

Eigenschaften eines Knotens — n_pbt_treeview_node #

Sein Handle, über of_node(adresse). Ein Lesen fragt den Baum, was der Knoten jetzt ist. Sein of_count() zählt seine Kinder, sein of_keys_at(n) liefert die Adresse seines n-ten Kindes (ab 1 gezählt), sein of_has(schlüssel) sagt, ob er dieses Kind hat, sein of_key() liefert seinen Schlüssel.

EigenschaftTypStandardZweck
is_textstring""Der Text des Knotens. Akzeptiert die Rich-Text-Auszeichnung. Leer zeigt der Knoten seinen Schlüssel
is_imagestring""Das Bild vor dem Text: eine Datei des Arbeitsplatzes, eine Ressource "datei.dll:name", ein im Design gezeichnetes Symbol "mono:…" / "tint:…", eine https://-Adresse. http:// wird abgelehnt (ue_image_failed, REASON_INSECURE)
is_expanded_imagestring""Das Bild, solange der Knoten offen ist (ein offener Ordner); "" behält is_image
is_state_imagestring""Das Statusbild des Knotens, vor seinem Bild: eine Flagge, ein Status — das StatePicture eines PowerBuilder-TreeView. Ein Klick darauf löst ue_state_clicked aus und wählt den Knoten nicht aus; dieselben Quellen und Ablehnungen wie is_image
is_overlay_imagestring""Ein kleines Bild, über die untere Ecke des Knotenbilds gezeichnet (ein Verknüpfungspfeil, ein Schloss) — das OverlayPicture eines PowerBuilder-TreeView
is_selected_imagestring""Das Bild des Knotens, solange er ausgewählt ist — das SelectedPicture eines PowerBuilder-TreeView. "" behält is_image
ib_expandedbooleanfalsetrue öffnet den Knoten (seine Kinder werden angezeigt), false schließt ihn; ue_node_toggled folgt, wie bei einem Klick auf seinen Chevron. Ein Knoten ohne Kinder liest sich false; das Öffnen eines Knotens, der Kinder nur verspricht, fordert sie an (ue_children_needed); sie kommen mit der Antwort, nachdem diese Zeile zurückgekehrt ist; mit ib_veto_toggle wird zuerst ue_node_toggling gefragt; abgelehnt, wird nichts gesendet und of_get_last_error sagt es
ib_has_childrenbooleanfalseEin Versprechen von Kindern: Der Chevron wird angezeigt, obwohl noch nichts hinzugefügt ist. Das Öffnen des Knotens löst ue_children_needed aus, wo Ihre Anwendung sie hinzufügt. Das Versprechen gilt bis zur Antwort, auch wenn ein Knoten hinzugefügt oder abgelegt wurde; es erneut auf true zu setzen, fragt bei der nächsten Öffnung wieder
ib_checkedbooleanfalseDer Haken des Knotens (ib_checkboxes des Baums). Mit ib_check_cascade hakt das Schreiben den ganzen Teilbaum an (ausgegraute Knoten eingeschlossen), und er liest sich true, wenn seine Kinder, die der Baum zeichnen kann, alle angehakt sind (of_check_state sagt gemischt); unter einem angehakten Blatt empfangene Kinder übernehmen dessen Haken. Ein von Ihrem Code geschriebener Haken löst nichts aus
ib_enabledbooleantruefalse graut den Knoten aus: Der Benutzer kann ihn weder auswählen, anhaken, umbenennen noch ziehen, auf seiner Zeile wird nichts abgelegt, die Tastatur überspringt ihn, und ein Haken des Benutzers an einem Elternknoten lässt ihn samt Teilbaum, wie er ist. Ihr Code wählt ihn weiterhin aus und hakt ihn an
ib_visiblebooleantruefalse nimmt den Knoten und seinen Teilbaum vom Bildschirm; er behält seine Adresse
is_badgestring""Ein kleines Badge nach dem Text (Auszeichnung erlaubt): eine Anzahl ungelesener Elemente; "" keines
ib_read_onlybooleanfalsetrue: Der Benutzer kann ihn weder umbenennen noch ziehen (er bleibt ein Ziel), und Entf lässt ihn aus; Ihr Code kann es weiterhin
ib_drop_targetbooleantruefalse: Nichts wird in ihn abgelegt, weder ein gezogener Knoten noch eine Datei des Explorers; davor oder dahinter bleibt erlaubt
ib_show_checkboxbooleantruefalse: kein Kästchen an diesem Knoten (ib_checkboxes) — er zählt nicht für seinen Elternknoten, steht nicht in of_checked_keys, und die Kaskade geht durch ihn hindurch zu seinen Kindern
of_keys ( ) → string——Gibt die Adresse des Knotens zurück: seine Schlüssel, mit / verbunden
of_level ( ) → long——Gibt seine Tiefe zurück: 1 für einen Knoten ganz oben, 2 für einen darin… 0, wenn der Baum ihn nicht enthält
of_position ( ) → long——Gibt seinen Platz unter den Kindern seines Elternknotens zurück, ab 1 gezählt, in der Reihenfolge des Hinzufügens (eine Sortierung ändert nur die angezeigte Reihenfolge); 0, wenn der Baum ihn nicht enthält
of_parent_keys ( ) → string——Gibt die Adresse seines Elternknotens zurück; "" für einen Knoten ganz oben
of_check_state ( ) → string——Gibt den Zustand seines Kästchens zurück: CHECK_ON, CHECK_OFF oder CHECK_MIXED (ein Teil seiner Kinder angehakt, mit ib_check_cascade); "", wenn der Baum ihn nicht enthält
of_row ( ) → long——Gibt die heutige Zeilennummer der Zeile, aus der der Knoten stammt, im DataStore von of_from_datastore zurück — welchen Schlüssel er auch nehmen musste, und nach einer Sortierung oder einem Filter des DataStores. 0 für einen von Hand hinzugefügten Knoten oder einen, dessen Zeile verschwunden ist; ein Knoten eines Loses liefert seine Zeile in seinem DataStore, ein Gruppenknoten 0; 0 auch, wenn der DataStore seines Loses für einen anderen Knoten neu geladen wurde
of_group_column ( ) → string——Für einen Gruppenknoten von is_group_by: die Spalte, nach der seine Ebene gruppiert ("region"); "" für jeden anderen Knoten
of_group_value ( ) → string——Für einen Gruppenknoten: der Wert seiner Spalte, für den er steht, wie die Zeilen ihn enthalten (ein Datum yyyy-mm-dd, eine Zahl mit Punkt, "" für die Gruppe der leeren Werte); "" für jeden anderen Knoten; ein Datum mit Uhrzeit yyyy-mm-dd hh:mm:ss, eine Uhrzeit hh:mm:ss
is_tooltipstring""Einfacher Tooltip beim Überfahren des Items
is_super_tooltip_titlestring""Titel des erweiterten Item-Tooltips (hat Vorrang vor is_tooltip)
is_super_tooltip_textstring""Text des erweiterten Item-Tooltips (Rich-Markup zulässig)
is_super_tooltip_imagestring""Bild des erweiterten Item-Tooltips
il_accentlong-1Akzent des Knotens: seine Auswahl (solange der Baum den Fokus hat) und sein angehaktes Kästchen übernehmen ihn; das Badge behält die Farbe des Designs (-1 = der der Komponente)
il_back_colorlong-1Hintergrund der Zeile des Knotens, als RGB(r,g,b) (-1 = was das Design vorgibt). Eine ausgewählte Zeile nimmt die Farben der Auswahl an
il_text_colorlong-1Textfarbe der Zeile des Knotens (-1 = was das Design vorgibt)
il_back_color_hoverlong-1Hintergrund der Zeile des Knotens unter dem Mauszeiger (-1 = was das Design vorgibt)
il_text_color_hoverlong-1Textfarbe der Zeile des Knotens unter dem Mauszeiger (-1 = was das Design vorgibt)

Eigenschaften einer Spalte — n_pbt_treeview_column #

Sein Handle, über of_column(schlüssel). Ein von Ihrem Code geschriebener Wert ist stumm, wie SetItem — außer seinem Layout: Von Ihrem Code geschriebene ii_width, ii_index und ib_visible lösen ue_layout_changed aus, wenn sich das Layout ändert, wie eine Geste. Ein Lesen liefert, was der Benutzer geändert haben mag (Breite, Platz).

EigenschaftTypStandardZweck
is_titlestring""Der Titel in der Kopfzeile (Auszeichnung erlaubt); "" zeigt den Schlüssel
ii_widthinteger0Die Breite in Pixeln: 0 ist automatisch (so breit wie der Titel und die gezeichneten Werte), sonst 40 bis 2000. Der Benutzer zieht den Rand der Kopfzeile: Ein Lesen liefert sie sofort
is_alignstringALIGN_STARTWo die Werte in ihren Zellen stehen: ALIGN_START, ALIGN_CENTER, ALIGN_END — Anfang und Ende der Leserichtung, die einer Rechts-nach-links-Anwendung folgen. Ein anderer Wert wird abgelehnt
is_formatstring""Wie ein Wert geschrieben wird: eine Zahlenmaske für eine Zahl ("#,##0.00", Trennzeichen der Anzeigesprache), die Datums-Token eines PowerBuilder-Anzeigeformats für ein Datum oder ein Datum mit Uhrzeit ("dd/mm/yyyy", "d mmm yyyy hh:mm" — mm nach einer Stunde sind die Minuten —, AM/PM, s, f, Literale "…", [shortdate], [longdate], [time]), dieselben wie beim datagrid; "" schreibt den Wert, wie er ist
ib_visiblebooleantruefalse nimmt die Spalte vom Bildschirm; sie behält ihren Platz und ihren Schlüssel
ii_indexinteger—Ihr Platz unter allen Spalten, ab 1 gezählt: Das Schreiben verschiebt die Spalte. Der Benutzer zieht auch eine Kopfzeile: Ein Lesen liefert ihn sofort
ib_sortablebooleantrueEin Klick auf ihre Kopfzeile sortiert den Baum nach dieser Spalte. Die Kopfzeile der Baumspalte (is_tree_title) sortiert immer, nach dem Text der Knoten
is_summarystring""Der Gesamtwert, den jeder Zweig in dieser Spalte zeigt: SUMMARY_SUM, SUMMARY_AVG, SUMMARY_MIN, SUMMARY_MAX, SUMMARY_COUNT (die nicht leeren Werte), aus dem, was seine Kinder bis zu den Blättern bringen, fett; SUMMARY_NONE (""): keine. of_get_field liest den Gesamtwert, eine Sortierung verwendet ihn; SUMMARY_COUNT wird als einfache Zahl geschrieben, nie über is_format; SUMMARY_MIN und SUMMARY_MAX vergleichen auch Datumswerte
ib_summary_over_valuebooleanfalsefalse: Ein Zweig mit eigenem Wert in der Spalte behält ihn (und gibt ihn nach oben weiter); true: Der Gesamtwert tritt an seine Stelle
il_accentlong-1Akzent der Kopfzeile: ihr Sortierpfeil und der Tastaturring übernehmen ihn (-1 = der der Komponente)
il_back_colorlong-1Hintergrund der Kopfzeile, als RGB(r,g,b) (-1 = was das Design vorgibt)
il_text_colorlong-1Textfarbe der Kopfzeile (-1 = was das Design vorgibt)
il_back_color_hoverlong-1Hintergrund der Kopfzeile unter dem Zeiger (-1 = was das Design vorgibt)
il_text_color_hoverlong-1Textfarbe der Kopfzeile unter dem Zeiger (-1 = was das Design vorgibt)
is_tooltipstring""Einfacher Tooltip beim Überfahren der Spaltenkopfzeile
is_super_tooltip_titlestring""Titel des erweiterten Tooltips der Kopfzeile (hat Vorrang vor is_tooltip)
is_super_tooltip_textstring""Text des erweiterten Tooltips der Kopfzeile (Rich-Markup zulässig)
is_super_tooltip_imagestring""Bild des erweiterten Tooltips der Kopfzeile

Konstanten #

Sie befinden sich auf u_pbt_treeview: u_pbt_treeview.CHECK_MIXED.

KonstanteWertBedeutung
SUMMARY_NONE""Kein Gesamtwert — der Standard
SUMMARY_SUM"sum"Die Summe
SUMMARY_AVG"avg"Der Durchschnitt der Blätter
SUMMARY_MIN"min"Der kleinste Wert
SUMMARY_MAX"max"Der größte Wert
SUMMARY_COUNT"count"Die Anzahl der nicht leeren Werte
SELECT_SINGLE"single"Jeweils ein ausgewählter Knoten — der Standard
SELECT_MULTIPLE"multiple"Mehrere, mit Strg und Umschalt
SELECT_NONE"none"Keiner: nur ein Fokus bewegt sich
SORT_ASC"asc"Aufsteigend
SORT_DESC"desc"Absteigend
SORT_NONE"none"Keine Sortierung: die Reihenfolge des Hinzufügens
CHECK_ON"on"Angehakt (mit Kaskade: der ganze Teilbaum)
CHECK_OFF"off"Nicht angehakt
CHECK_MIXED"mixed"Ein Teil der Kinder angehakt
ALIGN_START"start"Am Anfang der Leserichtung — der Standard
ALIGN_CENTER"center"In der Mitte
ALIGN_END"end"Am Ende der Leserichtung (Zahlen)
ROLE_KEY"key"Der Schlüssel des Knotens (eine ID); ohne sie die RowID
ROLE_PARENT"parent"Der Schlüssel des Knotens, der ihn enthält; mit einer Spalte ROLE_KEY nie eine RowID
ROLE_TEXT"text"Sein Text (als Text angezeigt)
ROLE_IMAGE"image"Sein Bild
ROLE_CHECKED"checked"Angehakt, wenn der Wert ja sagt (1, -1, true, y, yes, on, t, o; nein: 0, false, n, no, off, f, Groß-/Kleinschreibung egal); zurückgeschrieben, wie die Spalte es bereits tut; unter der Kaskade nur für ein Blatt gelesen: Ein Elternknoten ist dort der Zustand seiner Kinder
ROLE_BADGE"badge"Sein Badge
ROLE_EXPANDED"expanded"Beim Laden offen, wenn der Wert ja sagt
ROLE_HAS_CHILDREN"has_children"Die Zeile verspricht Kinder, wenn der Wert ja sagt: ein Chevron und ue_children_needed, wenn der Knoten sich öffnet; einmal gelesen, wenn der Knoten entsteht
ROLE_STATE_IMAGE"state_image"Sein Statusbild
ROLE_OVERLAY_IMAGE"overlay_image"Sein überlagertes Bild
EXPORT_ALL"all"Export: alle Knoten, geschlossene Zweige eingeschlossen — der Standard
EXPORT_SHOWN"shown"Export: die Zeilen auf dem Bildschirm
REASON_INSECURE"insecure"Eine http://-Adresse
REASON_NOT_FOUND"notfound"Eine nicht gefundene Datei
REASON_UNC"unc"Ein Netzwerkpfad aus einer DataStore-Spalte, vor jeder Anfrage abgelehnt

Methoden #

MethodeZweck
of_add_node (string as_keys, string as_text)Fügt einen Knoten an seiner Adresse hinzu, am Ende seines Elternknotens: "europe" ganz oben, "europe/france" in "europe" (zuerst hinzugefügt). as_text akzeptiert Auszeichnung ("" zeigt den Schlüssel). Gibt 0 zurück, sobald hinzugefügt, -5 für eine Adresse mit leerer Ebene, einen Schlüssel mit ` oder der mit __ beginnt, eine schon vergebene Adresse, einen unbekannten Elternknoten (of_get_last_error sagt welchen), -2`, wenn die Komponente nicht erstellt ist
of_add_node (string as_keys, string as_text, string as_image)Dasselbe mit seinem Bild (is_image des Handles). Gibt 0 zurück, sobald hinzugefügt, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_insert_node (string as_keys, string as_text, string as_image, long al_position)Fügt einen Knoten an einem Platz unter den Kindern seines Elternknotens hinzu, ab 1 gezählt (hinter dem letzten: am Ende). Gibt 0 zurück, sobald hinzugefügt, -5 wie of_add_node, -2, wenn die Komponente nicht erstellt ist
of_remove_node (string as_keys)Entfernt einen Knoten und alles, was er enthält (ihre Handles werden freigegeben). Das Entfernen des ausgewählten Knotens gibt die Auswahl an das weiter, was ihn enthielt (ue_selection_changed). Der Knoten einer DataStore-Zeile bleibt bis zum nächsten of_from_datastore weg: Weder of_map noch das erneute Lesen einer anderen Zeile bringt ihn zurück, of_reload_row seiner Zeile schon. Gibt 0 zurück, sobald entfernt, -5 für eine Adresse, die der Baum nicht enthält, -2, wenn die Komponente nicht erstellt ist
of_move_node (string as_keys, string as_to_parent_keys, long al_position)Verschiebt einen Knoten mit seinem Teilbaum unter einen anderen Elternknoten ("" = ganz oben), an einen Platz ab 1 (hinter dem letzten: am Ende) — oder an einen anderen Platz unter seinen Geschwistern. Seine Adresse ändert sich: Die an der alten Adresse geholten Handles werden durch diesen Aufruf sofort freigegeben; ein danach an der neuen geholter Handle bleibt gültig (eine Verschiebung unter denselben Geschwistern gibt nichts frei). Mit ib_veto_changes wird zuerst ue_node_moving gefragt, mit dem endgültigen Platz; mit ib_write_back schreibt ein Knoten einer Zeile, der den Elternknoten wechselt, diesen, bevor er sich bewegt (eine Verschiebung unter denselben Geschwistern schreibt nichts). ue_node_moved folgt, wie beim Ziehen. Was es schreibt, wird nach ue_node_moving erneut geprüft; bewegt sich der Knoten nicht, wird das Geschriebene zurückgesetzt. Gibt 0 zurück (auch wenn er schon dort ist: nichts wird gefragt, geschrieben oder ausgelöst), -4, wenn die Anwendung ablehnt oder der DataStore den Wert ablehnt (ue_write_back_failed), -5 für einen unbekannten Knoten oder Elternknoten, eine Verschiebung in den eigenen Teilbaum, einen unter dem neuen Elternknoten schon vergebenen Schlüssel, mit ib_write_back einen Knoten einer Zeile unter einem von Hand hinzugefügten Knoten oder unter einer Zeile ohne Schlüsselwert, einen Knoten eines Loses außerhalb seines Loses oder dessen DataStore für einen anderen Knoten neu geladen wurde, ein Blatt eines gruppierten Baums anderswo als unter einer Gruppe der letzten Ebene, einen Gruppenknoten, einen Knoten, der sich während ue_node_moving bewegt hat oder gegangen ist, -2, wenn die Komponente nicht erstellt ist
of_clear ( )Leert den Baum: Knoten, Handles und gelesene Zeilen (der DataStore bleibt für ein neues of_from_datastore gebunden); die Spalten und die Optionen bleiben. ue_selection_changed folgt, wenn Knoten ausgewählt waren. Die Spalten behalten ihre Farben und Tooltips. Die Bilder der Ebenen (of_set_level_image) bleiben ebenfalls. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist
of_node (string as_keys)Der Handle n_pbt_treeview_node eines Knotens, über seine Adresse (beim ersten Zugriff erstellt): sein Text, Bild, Haken, Zustände, Farben und Tooltip; eine unmögliche Adresse (leere Ebene, `, __`) liefert einen wirkungslosen Handle, der nichts liest und schreibt
of_edit_node (string as_keys)Öffnet den Text eines Knotens zur Bearbeitung aus Ihrem Code — das EditLabel eines PowerBuilder-TreeView. Der Knoten wird zuerst ausgewählt (in SELECT_NONE nur in den Blick gebracht), dann öffnet sich das Feld; das Ende gehört dem Benutzer (Eingabe: ue_node_editing, dann ue_node_edited; Esc oder of_cancel_edit stellt den Text wieder her). Funktioniert mit ib_editable = false, auf einem schreibgeschützten oder ausgegrauten Knoten. Gibt 0 zurück, sobald das Feld offen ist, -5 für einen Knoten, den der Baum nicht hält oder nicht zeichnen kann, einen ausgegrauten Baum, einen Gruppenknoten von is_group_by oder eine Zeile, deren DataStore unter ib_write_back keine Spalte ROLE_TEXT hat (of_get_last_error sagt welche), -4, wenn ue_selection_changing (oder ue_node_toggling) abgelehnt hat, -2, wenn die Komponente nicht erstellt ist
of_cancel_edit ( )Schließt das Feld einer laufenden Bearbeitung (vom Benutzer oder von of_edit_node geöffnet) und stellt den Text wieder her, wie Esc: nichts wird ausgelöst. Gibt 0 zurück, sobald angewendet (keine laufende Bearbeitung: 0, nichts ändert sich), -2, wenn die Komponente nicht erstellt ist
of_expand_all ( )Öffnet alle Knoten, die Kinder haben (ein nur versprochener Zweig bleibt geschlossen: nichts wird angefordert). ue_node_toggled folgt für jeden, dann einmal ue_layout_changed. Gibt 0 zurück, sobald angewendet, -4, wenn ue_node_toggling einige abgelehnt hat, -2, wenn die Komponente nicht erstellt ist
of_collapse_all ( )Schließt alle Knoten. ue_node_toggled folgt für jeden, der offen war, dann einmal ue_layout_changed. Gibt 0 zurück, sobald angewendet, -4, wenn ue_node_toggling einige abgelehnt hat, -2, wenn die Komponente nicht erstellt ist
of_expand_all (string as_keys)Öffnet einen Knoten und jeden Knoten unter ihm, der Kinder hat (das ExpandAll(handle) von PowerBuilder); "" = der ganze Baum. Gibt 0 zurück, sobald angewendet, -4, wenn ue_node_toggling einige abgelehnt hat, -5 für einen Knoten, den der Baum nicht enthält, -2, wenn die Komponente nicht erstellt ist
of_collapse_all (string as_keys)Schließt einen Knoten und jeden Knoten unter ihm; "" = der ganze Baum. Gibt 0 zurück, sobald angewendet, -4, wenn ue_node_toggling einige abgelehnt hat, -5 für einen Knoten, den der Baum nicht enthält, -2, wenn die Komponente nicht erstellt ist
of_expand_to_level (long al_level)Zeigt den Baum bis zu einer Ebene: Die Ebenen über al_level öffnen sich, diese Ebene und die folgenden schließen sich (1: nur die oberste ist sichtbar). Ein Zweig, dessen Versprechen nicht beantwortet wurde, bleibt geschlossen. ue_node_toggled für jeden geänderten Knoten, dann ue_layout_changed. Gibt 0 zurück, sobald angewendet, -4, wenn ue_node_toggling einige abgelehnt hat, -5 für eine Ebene unter 1, -2, wenn die Komponente nicht erstellt ist
of_set_level_image (integer ai_level, string as_image, string as_expanded_image)Das Bild jedes Knotens einer Ebene (1 = ganz oben), der kein eigenes hat — das SetLevelPictures von PowerBuilder, praktisch für einen gruppierten Baum: as_image und as_expanded_image, solange der Knoten offen ist ("" behält as_image). Zweimal "" entfernt die Bilder der Ebene. Gibt 0 zurück, sobald gesetzt, -5 für eine Ebene unter 1, -2, wenn die Komponente nicht erstellt ist
of_clear_children (string as_keys)Entfernt die Kinder eines Knotens (ihre Handles werden freigegeben; ein Knoten einer Zeile bleibt bis zum nächsten of_from_datastore weg) und behält den Knoten, der erneut verspricht: Sein nächstes Öffnen löst ue_children_needed aus — das „Aktualisieren“ eines Ordners. Offen, schließt er sich (ue_node_toggled). Es schließt, ohne ue_node_toggling zu fragen, und ue_layout_changed folgt. Gibt 0 zurück, sobald angewendet, -5 für einen Knoten, den der Baum nicht enthält, -2, wenn die Komponente nicht erstellt ist
of_scroll_to_node (string as_keys)Zeigt einen Knoten: Was ihn enthält, öffnet sich (ue_node_toggled für jeden, vom äußersten an), dann rollt der Baum, bis er sichtbar ist. Die Auswahl ändert sich nicht. Ein Knoten, den der Baum nicht zeichnen könnte, wird abgelehnt, bevor sich etwas öffnet. Gibt 0 zurück, sobald angewendet, -5 für einen Knoten, den der Baum nicht enthält oder nicht zeichnet (ausgeblendet oder in einem ausgeblendeten enthalten, jenseits der Demogrenze, von der Suche ausgeschlossen; of_get_last_error sagt, was), -4, wenn ue_node_toggling das Öffnen eines ihn enthaltenden Knotens ablehnt (ib_veto_toggle), -2, wenn die Komponente nicht erstellt ist
of_select_node (string as_keys)Wählt einen Knoten allein aus, wie ein Klick: Was ihn enthält, öffnet sich (ein versprochener Zweig stellt seine Frage), der Fokus geht auf ihn und er kommt in Sicht; ue_selection_changed folgt (schon allein ausgewählt: nichts wird ausgelöst). Ein ausgegrauter Knoten wird ebenfalls ausgewählt: Ausgegraut hält den Benutzer auf, nicht Ihren Code. Der Knoten wird zuerst geprüft: Ein Baum öffnet, um auszuwählen, wie die TreeView von Windows, doch für einen abgelehnten Knoten öffnet sich nichts. Mit beiden Vetos werden zuerst die Öffnungen gefragt (ue_node_toggling), dann die Auswahl (ue_selection_changing). Gibt 0 zurück, sobald ausgewählt, -5 für einen Knoten, den der Baum nicht enthält oder nicht zeichnet (ausgeblendet oder in einem ausgeblendeten enthalten, jenseits der Demogrenze, von der Suche ausgeschlossen; of_get_last_error sagt, was), oder wenn is_selection_mode SELECT_NONE ist, -4, wenn ue_selection_changing die Auswahl ablehnt (ib_veto_selection) oder ue_node_toggling einen zu öffnenden Knoten (ib_veto_toggle), -2, wenn die Komponente nicht erstellt ist
of_select_nodes (string as_keys_json)Wählt mehrere Knoten auf einmal aus — das Gegenstück zu of_selected_keys: as_keys_json ist ein JSON-Array von Adressen, in beliebiger Reihenfolge (["europe/france","asia"], eine doppelte Adresse zählt einmal). Jeder Knoten wird zuerst geprüft (vorhanden und zeichenbar, sobald geöffnet ist, was ihn enthält); dann öffnet sich, was sie enthält, Fokus und Anker gehen auf die letzte genannte Adresse, und ue_selection_changed folgt einmal. Mit ib_veto_toggle wird ue_node_toggling für jeden Knoten gefragt, den es öffnet, dann mit ib_veto_selection ue_selection_changing einmal für die ganze Auswahl. "[]" lässt nichts ausgewählt; in SELECT_SINGLE höchstens eine Adresse. Gibt 0 zurück, sobald ausgewählt (auch wenn diese Auswahl schon besteht: nichts wird ausgelöst), -4 abgelehnt, -5 für einen Text, der kein JSON-Array von Adressen ist, eine Adresse, die der Baum nicht enthält oder nicht zeichnet (of_get_last_error sagt welche), mehr als eine Adresse in SELECT_SINGLE oder SELECT_NONE, -2, wenn die Komponente nicht erstellt ist
of_clear_selection ( )Lässt keinen Knoten ausgewählt: ue_selection_changed("[]") folgt (schon nichts ausgewählt: nichts wird ausgelöst). Gibt 0 zurück, sobald angewendet, -4, wenn ue_selection_changing ablehnt, -2, wenn die Komponente nicht erstellt ist
of_selected_key ( )Die Adresse des ausgewählten Knotens (der mit dem Fokus, wenn mehrere es sind); sonst "". Live gelesen
of_selected_keys ( )Die Adressen aller ausgewählten Knoten, als JSON-Array in der Reihenfolge des Baums: ["europe/france","asia"]; "[]", wenn keiner. Live gelesen; mit n_pbt_json zu lesen
of_checked_keys ( )Die Adressen aller angehakten Knoten, als JSON-Array in der Reihenfolge des Baums. Mit ib_check_cascade gehört ein Knoten, dessen ganzer Teilbaum angehakt ist, dazu, ein gemischter nicht. Live gelesen
of_check_all (boolean ab_checked)Hakt alle Knoten auf einmal an (oder ab). Ein vom Code geschriebener Haken ist ein Wert: nichts wird ausgelöst. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist
of_sort (string as_column, string as_dir)Sortiert die angezeigten Knoten, auf jeder Ebene: nach einer Spalte (ihr Schlüssel) oder nach dem Text der Knoten (as_column = ""). as_dir: SORT_ASC, SORT_DESC oder SORT_NONE (die Reihenfolge des Hinzufügens). Die Reihenfolge des Modells (of_keys_at, of_position) ändert sich nicht. ue_sort_changed und dann ue_layout_changed folgen, wie bei einem Klick auf eine Kopfzeile. as_column kann auch ein Feld nennen, das keine Spalte zeigt; eine zusammengefasste Spalte sortiert nach ihren Gesamtwerten, und mit ib_parents_first bleiben die Zweige vor den Blättern. as_column "text" ist der Text der Knoten, wie "". Gibt 0 zurück, sobald angewendet (auch wenn die Sortierung schon diese ist: nichts wird ausgelöst), -5 für einen Namen, der keiner ist (Buchstaben, Ziffern und _), oder eine unbekannte Richtung, -2, wenn die Komponente nicht erstellt ist
of_sort (string as_sort)Sortiert nach mehreren Schlüsseln in ihrer Reihenfolge: Der erste entscheidet, die folgenden lösen Gleichstände. as_sort wird so geschrieben, wie das SetSort eines DataWindows es liest — "type A, text D" (auch asc und desc, ohne Richtung = aufsteigend, text = der Text der Knoten, jeder andere Name eine Spalte oder ein Feld); "" entfernt die Sortierung. ue_sort_changed, dann ue_layout_changed folgen. Mehrere Leerzeichen zwischen einer Spalte und ihrer Richtung werden akzeptiert, wie von SetSort. Gibt 0 zurück, sobald sortiert (auch wenn es schon diese Sortierung ist: nichts wird ausgelöst), -5 für einen Namen, der keiner ist, eine andere Richtung oder einen doppelt genannten Schlüssel, -2, wenn die Komponente nicht erstellt ist
of_find_node (string as_field, string as_value, string as_after_keys)Die Adresse des ersten Knotens, dessen Feld genau as_value enthält (Groß-/Kleinschreibung zählt): as_field "" = der Text des Knotens, jeder andere Name ein Feld (Ihres, eine Spalte des DataStores, der Gesamtwert einer zusammengefassten Spalte). In der Reihenfolge, die der Baum zeigt, geschlossene Zweige und von der Suche ausgeschlossene Knoten eingeschlossen, nie ein ausgeblendeter Knoten; as_after_keys "" beginnt beim ersten Knoten, sonst nach diesem: Übergeben Sie die gefundene Adresse erneut für den nächsten. "", wenn es keinen gibt (of_get_last_error sagt warum, wenn die Argumente abgelehnt wurden). Es beginnt nach dem Platz von as_after_keys in der angezeigten Reihenfolge — auch bei einem ausgeblendeten Knoten; ein unbekanntes as_after_keys oder ein Aufruf während einer Wartezeit liefert "", und of_get_last_error sagt warum (dieses Lesen leert es zuerst). of_find_nodes liefert alle auf einmal
of_find_nodes (string as_field, string as_value)Alle Knoten, deren Feld genau as_value enthält (Groß-/Kleinschreibung zählt), in einem Durchgang: ihre Adressen als JSON-Array in der Reihenfolge, die der Baum zeigt (["europe/france","asia"]); "[]", wenn keiner. as_field "" ist der Text des Knotens, jeder andere Name ein Feld. Geschlossene Zweige und von der Suche ausgeschlossene Knoten werden durchsucht, nie ein ausgeblendeter Knoten (im Demomodus auch keiner jenseits der Grenze). "[]" mit of_get_last_error, wenn der Feldname keiner ist oder während einer Wartezeit. Lesen Sie es mit n_pbt_json
of_search_next ( )Wählt den nächsten von der Suche gefundenen Knoten aus (is_filter), nach dem Knoten mit dem Fokus, im Kreis; F3 tut dasselbe. Wie of_select_node: ue_selection_changed folgt, und mit ib_veto_selection wird zuerst ue_selection_changing gefragt. In SELECT_NONE bewegt es den Fokus dorthin und gibt 0 zurück; während einer Wartezeit gibt es -5 zurück, und of_get_last_error sagt warum. Gibt 0 zurück, sobald ausgewählt, -4 abgelehnt, -5 ohne Suche oder ohne Treffer, -2, wenn die Komponente nicht erstellt ist
of_search_prev ( )Wählt den vorigen von der Suche gefundenen Knoten aus, vor dem Knoten mit dem Fokus, im Kreis; Umschalt+F3 tut dasselbe. In SELECT_NONE bewegt es den Fokus dorthin und gibt 0 zurück; während einer Wartezeit gibt es -5 zurück, und of_get_last_error sagt warum. Gibt 0 zurück, sobald ausgewählt, -4 abgelehnt, -5 ohne Suche oder ohne Treffer, -2, wenn die Komponente nicht erstellt ist
of_match_count ( )Gibt zurück, wie viele Knoten die Suche (is_filter) gefunden hat, sofort gelesen; 0 ohne Suche
of_add_column (string as_key, string as_title)Fügt am Ende eine Spalte hinzu: Der Baum wird zur Baumliste, die erste Spalte trägt den Baum, diese zeigt das Feld mit demselben Schlüssel jedes Knotens (of_set_field oder die Spalte des DataStores). Ihre Breite ist automatisch. Der Schlüssel text wird abgelehnt (-5): Er bezeichnet den Text der Knoten. Gibt 0 zurück, sobald hinzugefügt, -5 für einen Schlüssel, der keiner sein kann (leer, mit / oder `, mit __ beginnend), oder eine schon vorhandene Spalte, -2`, wenn die Komponente nicht erstellt ist
of_add_column (string as_key, string as_title, integer ai_width)Dasselbe mit einer Breite in Pixeln (0 = automatisch; 40 bis 2000). Gibt 0 zurück, sobald hinzugefügt, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_remove_column (string as_key)Entfernt eine Spalte (ihr Handle wird freigegeben); ist die letzte weg, wird die Liste wieder ein Baum. Das Entfernen der sortierten Spalte löst ue_sort_changed mit dem nächsten Schlüssel der Sortierung aus — SORT_NONE, wenn es der einzige war —, dann ue_layout_changed. Gibt 0 zurück, sobald entfernt, -5 für eine Spalte, die die Liste nicht enthält, -2, wenn die Komponente nicht erstellt ist
of_clear_columns ( )Entfernt alle Spalten (ihre Handles werden freigegeben): Die Liste wird wieder ein Baum. Das Entfernen der sortierten Spalte löst ue_sort_changed mit dem nächsten Schlüssel der Sortierung aus — SORT_NONE, wenn es der einzige war —, dann ue_layout_changed. Gibt 0 zurück, sobald angewendet, -2, wenn die Komponente nicht erstellt ist
of_column (string as_key)Der Handle n_pbt_treeview_column einer Spalte (beim ersten Zugriff erstellt): Titel, Breite, Ausrichtung, Format, Sichtbarkeit, Platz und ob ein Klick auf ihre Kopfzeile sortiert
of_set_field (string as_keys, string as_field, string as_value)Gibt einem Knoten ein eigenes Feld: of_set_field("europe/france", "population", "68000000"); die Spalte mit dem Schlüssel population zeigt es. Ein Knoten eines DataStores hat jede Spalte schon als Feld; ein eigenes Feld mit demselben Namen hat Vorrang. Ein Feldname: Buchstaben, Ziffern und _, nicht mit einer Ziffer beginnend. Gibt 0 zurück, sobald gesetzt, -5 für einen unbekannten Knoten oder einen ungültigen Namen, -2, wenn die Komponente nicht erstellt ist
of_get_field (string as_keys, string as_field)Liest ein Feld eines Knotens, live: eines Ihrer eigenen (of_set_field), eine Spalte des DataStores, aus dem er stammt, oder ein eingebautes (key, keys, text, badge, level, position, count, image). "", wenn er keines hat; für eine zusammengefasste Spalte (is_summary) der rohe Gesamtwert des Zweigs, eine Zahl mit Punkt; das eingebaute count zählt die Kinder, die der Baum zeichnen kann
of_from_datastore (datastore ads)Speist den Baum aus einem DataStore: eine Zeile = ein Knoten (siehe oben). Die Knoten eines früheren Ladens gehen (ihre Handles werden freigegeben); die von Hand ganz oben hinzugefügten Knoten bleiben, ihre Handles auch. Zwei Zeilen mit demselben Schlüssel: Die zweite erhält "schlüssel~RowID"; ein unmöglicher Schlüssel (mit / oder ` oder mit __ beginnend): die RowID — seine Kinder finden ihn weiterhin über seinen Wert. Mit einer Spalte ROLE_KEY nennt ein Elternwert einen Schlüssel, nie eine RowID. Datums- und Zahlenwerte werden unabhängig von den Regionaleinstellungen gelesen (Datum yyyy-mm-dd, hh:mm:ss, Zahl mit Punkt). Was das Laden korrigieren musste (fehlende Elternknoten, Schleifen, doppelte oder unmögliche Schlüssel), sagt of_get_last_error, die Rückgabe bleibt 0. Mit is_group_by sind die Zeilen die Blätter von Gruppen (ROLE_PARENT spielt keine Rolle). Ein neues Laden nimmt die unter seinen Zeilen hängenden Lose mit und behält die unter einem von Hand hinzugefügten Knoten hängenden. Ein neues Laden gibt nur die Handles dessen frei, was es ersetzt (ein von Hand hinzugefügter Knoten, ein inaktives Handle, eine noch nicht erstellte Adresse behalten ihres); ein ohne ib_write_back verschobener Knoten einer Zeile kehrt an den Platz zurück, den seine Zeile sagt. Der Bericht von of_get_last_error zählt auch die an die Spitze gehobenen, von Hand hinzugefügten Knoten (lifted=N) und die mit ihrem Knoten gegangenen Lose (lots=N). Gibt 0 zurück, sobald geladen, -5, wenn der DataStore nicht gültig ist, keine Spalte hat oder eine von of_map genannte Spalte fehlt (of_get_last_error nennt sie), -2`, wenn die Komponente nicht erstellt ist
of_from_datastore (datawindow adw)Dasselbe aus den Zeilen eines DataWindows: Der Baum schreibt in dieses DataWindow zurück (ib_write_back), das der Benutzer daneben sieht. Ihre Daten werden mit einem Hilfs-DataStore geteilt: Eine DataWindow, die sie nicht teilen kann, wird abgelehnt (-5, mit dem Grund). Gibt 0 zurück, sobald geladen, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_from_datastore (datawindowchild adwc)Dasselbe aus den Zeilen eines DataWindowChilds (ein DropDown-DataWindow, ein verschachtelter Bericht): Der Baum schreibt dorthin zurück. Gibt 0 zurück, sobald geladen, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_from_datastore (datastore ads, string as_parent_keys)Ein Los: Die Zeilen eines DataStores werden zu Kindern des Knotens as_parent_keys, der übrige Baum bewegt sich nicht — was ue_children_needed mit einem einzigen Aufruf tut. Eine Rolle wird für jeden DataStore aufgelöst: die Spalte von of_map(ads, …) für diesen, sonst die von of_map, wenn er sie hat, sonst die nach der Rolle benannte Spalte; ROLE_PARENT nennt eine Zeile desselben Loses (leer oder unbekannt: der Knoten selbst). Derselbe DataStore, erneut unter demselben Knoten übergeben, ersetzt sein Los (seine Handles werden freigegeben), ein anderer fügt seines hinzu; of_row eines Knotens des Loses ist seine Zeile in diesem DataStore, und ib_write_back schreibt dorthin. Ein unter dem Knoten schon vergebener Schlüssel erhält "Schlüssel~RowID". Ein DataStore pro Los: Für einen anderen Knoten neu geladen (Reset, Retrieve — PowerBuilder vergibt dieselben RowIDs erneut), nimmt er seine Zeilen zum neuen Los mit, und die Knoten des früheren Loses behalten, was sie zeigen, ohne Zeile (of_row 0, eine Verschiebung durch den Code -5, ein Zurückschreiben mit ue_write_back_failed abgelehnt; das Laden zählt stale=N). Um ein Los aus einem anderen DataStore-Objekt aufzufrischen, zuerst of_clear_children. Gibt 0 zurück, sobald geladen, -5, wenn der DataStore nicht gültig ist, keine Spalte hat, eine von of_map(ads, …) für ihn genannte Spalte fehlt oder as_parent_keys leer ist (die Spitze des Baums ist of_from_datastore(ads)) oder kein Knoten des Baums ist, -2, wenn die Komponente nicht erstellt ist
of_from_datastore (datawindow adw, string as_parent_keys)Ein Los aus den Zeilen eines DataWindows (siehe oben). Gibt 0 zurück, sobald geladen, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_from_datastore (datawindowchild adwc, string as_parent_keys)Ein Los aus den Zeilen eines DataWindowChilds. Gibt 0 zurück, sobald geladen, -5 wie oben, -2, wenn die Komponente nicht erstellt ist
of_row_keys (long al_row)Die Adresse des Knotens einer Zeile des DataStores von of_from_datastore (des Haupt-DataStores, nicht eines Loses), über ihre heutige Zeilennummer: Entfernen Sie den Knoten (of_remove_node) vor dem DeleteRow. "", wenn die Zeile keinen Knoten hat (entfernt, nie geladen, keine solche Zeile). "" auch, sobald der Haupt-DataStore erneut als Los übergeben wurde, bis zum nächsten Hauptladen
of_map (string as_role, string as_column)Gibt einer Spalte des DataStores eine Rolle (ROLE_KEY, ROLE_PARENT, ROLE_TEXT…), wenn ihr Name es nicht sagt: of_map(ROLE_PARENT, "manager_id"). Die Rolle gilt für jeden DataStore, der diese Spalte hat: Ein aus einem DataStore ohne sie gelesenes Los nimmt die nach der Rolle benannte Spalte, und of_map(ads, …) gibt einem DataStore seine eigenen Rollen. Vor oder nach of_from_datastore: danach werden die Zeilen neu gelesen, und was an den Knoten gesetzt wurde, bleibt. "" als Spalte gibt die Rolle der gleichnamigen Spalte zurück. Ein neuer ROLE_KEY oder ROLE_PARENT gibt neue Adressen: Nur die Handles der Knoten, deren Adresse sich geändert hat, werden freigegeben, die anderen bleiben gültig. Die vergebenen Rollen bleiben für die folgenden of_from_datastore erhalten, auch nach of_clear; nur of_reset vergisst sie. Sein Lesen der Zeilen meldet in of_get_last_error, was es für alle Quellen korrigieren musste. Gibt 0 zurück, sobald gesetzt, -5, wenn die Rolle keine ROLE_-Konstante ist oder die Spalte nicht zum DataStore des letzten of_from_datastore gehört, -2, wenn die Komponente nicht erstellt ist
of_map (datastore ads, string as_role, string as_column)Gibt einer Spalte eine Rolle nur für diesen DataStore: Das Los der Abteilungen und das der Mitarbeiter eines Baums benennen jeweils ihren Schlüssel und ihren Text. Geht für diesen DataStore of_map(as_role, as_column) vor; "" gibt die Rolle zurück. Vor oder nach of_from_datastore: danach werden die Zeilen neu gelesen, was an den Knoten gesetzt wurde, bleibt. Gibt 0 zurück, sobald gesetzt, -5, wenn der DataStore nicht gültig ist, die Rolle keine ROLE_-Konstante ist oder der DataStore keine solche Spalte hat, -2, wenn die Komponente nicht erstellt ist
of_map (datawindow adw, string as_role, string as_column)Dasselbe für die Zeilen eines DataWindows, das of_from_datastore übergeben wurde. Gibt 0 zurück, sobald gesetzt, -5 für ein abgelehntes Argument, -2, wenn die Komponente nicht erstellt ist
of_map (datawindowchild adwc, string as_role, string as_column)Dasselbe für die Zeilen eines DataWindowChild, das of_from_datastore übergeben wurde. Gibt 0 zurück, sobald gesetzt, -5 für ein abgelehntes Argument, -2, wenn die Komponente nicht erstellt ist
of_reload_row (long al_row)Sendet eine Zeile des DataStores von of_from_datastore erneut an den Baum, jetzt gelesen: nachdem Ihr Code sie geändert hat (SetItem, ein Bearbeitungsfenster). al_row ist die heutige Zeilennummer; der Knoten folgt der Zeile an Ort und Stelle: Was an ihm gesetzt wurde (offen, ausgegraut, sichtbar, Felder, Farben), bleibt, nichts wird ausgelöst. Eine Zeile, deren Schlüssel oder Elternknoten sich geändert hat, verschiebt ihren Knoten (die Handles dessen, was sich bewegt hat, werden freigegeben, die anderen bleiben gültig); eine Zeile, die der Baum noch nicht hat (InsertRow), kommt ebenfalls an, an ihrem Rang unter ihren Geschwistern; die Zeile eines durch of_remove_node entfernten Knotens kehrt zurück. Jeder Wert wird so geschrieben, wie das Laden ihn schreibt. Nur der Haupt-DataStore wird gelesen, kein Los (übergeben Sie es erneut); in einem gruppierten Baum geht eine Zeile, deren Gruppenwert sich geändert hat, in ihre neue Gruppe. Sobald der Haupt-DataStore erneut als Los übergeben wurde, gibt es bis zum nächsten Hauptladen -5 zurück; eine Zeile, deren Elternknoten oder Gruppe sich ändert, verschiebt ihren Knoten an Ort und Stelle. Gibt 0 zurück, sobald gesendet, -5, wenn kein DataStore gebunden ist, der Baum seit dem Laden durch of_clear geleert wurde oder die Zeile nicht existiert, -2, wenn die Komponente nicht erstellt ist
of_export_csv (string as_path)Schreibt den Baum in eine CSV-Datei (UTF-8, Semikolon) mit seiner Hierarchie: der Text eines Knotens in der Zelle seiner Ebene, die Spalten nach der tiefsten Ebene, zuerst eine Kopfzeile; eine Zahl roh, mit dem Dezimalzeichen der Anzeigesprache. is_export_scope sagt, welche Knoten; ue_csv_saved bestätigt; ein relativer Pfad wird im Startordner der Anwendung geschrieben. Im Demomodus abgelehnt. Gibt 0 zurück, sobald angefordert, -5, wenn der Pfad leer ist, -2, wenn die Komponente nicht erstellt ist
of_export_xlsx (string as_path)Schreibt den Baum in eine Excel-Arbeitsmappe (.xlsx): der Text eines Knotens in der ersten Spalte, um seine Ebene eingerückt und unter seinem Elternknoten gruppiert (die Gliederungsebenen von Excel: jeder Zweig klappt mit dem + / - am Rand ein, bis zu 7 Ebenen, alles geöffnet geschrieben), die Spalten danach, Zahlen bleiben Zahlen (mit dem Format ihrer Spalte, wenn es eine Zahlenmaske ist). is_export_scope sagt, welche Knoten; ue_xlsx_saved bestätigt. Im Demomodus abgelehnt. Gibt 0 zurück, sobald angefordert, -5, wenn der Pfad leer ist, -2, wenn die Komponente nicht erstellt ist
of_get_layout ( )Was der Benutzer angeordnet hat, als JSON: {"columns":[{"key":"","width":260,"visible":true},…],"sort":{"column":"","dir":"none"},"expanded":["europe"]} — zuerst die Baumspalte (Schlüssel ""), dann jede Spalte in ihrer Reihenfolge mit ihrer Breite (0 = automatisch) und Sichtbarkeit, die Sortierung, die offenen Knoten. Zu speichern (Datei, Registry, Datenbank) und dann an of_set_layout zurückzugeben. Live gelesen. Es enthält auch "sorts" (alle Schlüssel der Sortierung), "selected" (die ausgewählten Knoten) und "top" (den obersten Knoten der Ansicht, nie Pixel)
of_set_layout (string as_layout_json)Stellt ein über of_get_layout gelesenes oder per ue_layout_changed empfangenes Layout wieder her: Breiten, Reihenfolge und Sichtbarkeit der Spalten, Sortierung und welche Knoten offen sind (die nicht genannten schließen sich). Eine genannte Spalte oder ein genannter Knoten, den der Baum nicht enthält, wird ignoriert. ue_layout_changed wird einmal ausgelöst, wenn sich etwas geändert hat (weder ue_node_toggled noch ue_sort_changed: Es stellt einen Zustand wieder her). Es gibt auch die Auswahl zurück (ue_selection_changed, wenn sie sich geändert hat, nichts wird gefragt) und rollt bis zum obersten Knoten. Eine Adresse, die es in einem noch nicht beantworteten Zweig offen verlangt, wird gemerkt: Sie öffnet sich von selbst, wenn die Antwort ihres Zweigs sie bringt (ue_node_toggled, dann ue_layout_changed); ue_selection_changed wird nur einmal ausgelöst. Die Fragen von ib_veto_selection und ib_veto_toggle werden nicht gestellt: Es stellt einen Zustand wieder her, typischerweise beim Start. Ein versprochener Zweig, der schon einen Knoten enthält, wird nicht über die Hälfte seines Inhalts geöffnet: Er fragt zuerst ue_children_needed. Gibt 0 zurück, sobald angewendet, -5, wenn der Text leer oder kein JSON-Objekt ist, -2, wenn die Komponente nicht erstellt ist

Ereignisse #

EventAusgelöst wenn
ue_node_clicked (string as_keys)Ein Knoten wurde angeklickt (und ausgewählt, außer in SELECT_NONE). Ein Klick auf den Chevron oder das Kästchen löst es nicht aus; ein ausgegrauter Knoten löst nichts aus
ue_node_opened (string as_keys)Ein Doppelklick auf einen Knoten oder Eingabe: Öffnen Sie Ihren Editor dafür. Ein Doppelklick auf einen Zweig öffnet oder schließt ihn auch (ue_node_toggled)
ue_node_rclicked (string as_keys, long al_x, long al_y)Ein Rechtsklick auf einen Knoten (zuerst ausgewählt, außer ue_selection_changing lehnt es ab oder der Modus ist SELECT_NONE: Handeln Sie auf as_keys, nie auf of_selected_key) oder die Kontextmenütaste (oder Umschalt + F10) auf dem Knoten mit dem Fokus. al_x, al_y sind Bildschirmpixel — der Punkt des Klicks oder die untere linke Ecke des Knotens für die Kontextmenütaste —, die ein contextmenu erwartet: uo_menu.of_show(al_x, al_y); für ein PowerBuilder-Menü PopMenu(PointerX(), PointerY()) Ihres Fensters
ue_node_toggled (string as_keys, boolean ab_expanded)Ein Knoten hat sich geöffnet (ab_expanded = true) oder geschlossen: sein Chevron, ein Doppelklick, die Tastatur oder Ihr Code (ib_expanded, of_expand_all, of_collapse_all und was of_select_node oder of_scroll_to_node öffnen); eine während ue_children_needed ausgeführte Öffnung löst es nur einmal aus; of_expand_to_level, of_clear_children (das schließt) und ein von of_set_layout gemerkter Zweig lösen es ebenfalls aus
ue_selection_changed (string as_keys_json)Die Auswahl hat sich geändert: ein Klick, die Tastatur, Ihr Code (of_select_node, of_clear_selection) oder ausgewählte Knoten, die den Bildschirm verlassen haben (Zweig geschlossen, Knoten entfernt oder ausgeblendet, Knoten von der Suche verborgen — was ihn enthält, wird nicht an seiner Stelle ausgewählt). as_keys_json ist das JSON-Array der ausgewählten Adressen in der Reihenfolge des Baums: ["europe/france", "asia"]
ue_node_checked (string as_keys, boolean ab_checked)Der Benutzer hat einen Knoten angehakt (ab_checked = true) oder abgehakt: sein Kästchen oder die Leertaste. Mit ib_check_cascade folgt sein ganzer Teilbaum, schon an Ort und Stelle, wenn das Ereignis eintrifft. Ein von Ihrem Code geschriebener Haken löst nichts aus. Ein Haken des Benutzers überspringt einen ausgegrauten Knoten und seinen Teilbaum
ue_children_needed (string as_keys)Ein durch ib_has_children versprochener Zweig öffnet sich und enthält seine Kinder noch nicht: Fügen Sie sie jetzt hinzu (of_add_node); der Zweig öffnet sich mit ihnen, wenn das Ereignis zurückkehrt, nachdem die Zeile, die ihn geöffnet hat, zurückgekehrt ist. Das Versprechen gilt bis zu dieser Antwort, auch wenn ein Knoten hinzugefügt oder abgelegt wurde; unter einem angehakten Blatt übernimmt jedes hinzugefügte Kind dessen Haken. Fügen Sie nichts hinzu, wird das Versprechen zurückgezogen (der Chevron verschwindet)
ue_node_editing (string as_keys, string as_text) → booleanAbbrechbar, bevor ein vom Benutzer getippter Text behalten wird, nur wenn ib_veto_changes = true. FALSE zurückzugeben lehnt ab: Der Knoten behält seinen Text. Standard: TRUE
ue_node_edited (string as_keys, string as_text, string as_old_text)Der Benutzer hat einen Knoten umbenannt (F2 oder ein langsamer zweiter Klick mit ib_editable). Der Knoten zeigt schon as_text; as_old_text ist der, den er hatte. Mit ib_write_back ist der DataStore schon geschrieben
ue_node_moving (string as_keys, string as_to_parent_keys, long al_position) → booleanAbbrechbar, vor dem Verschieben eines Knotens gefragt (Ziehen oder of_move_node), nur wenn ib_veto_changes = true. as_to_parent_keys ist "" für ganz oben, al_position sein endgültiger Platz dort, ab 1 gezählt, auf die Geschwister begrenzt — der, den ue_node_moved nennen wird. Ein Knoten, der schon dort ist, fragt nichts. FALSE zurückzugeben lehnt ab: Nichts bewegt sich, und of_move_node gibt -4 zurück. Ein im Ereignis ausgeführtes of_move_node desselben Knotens wird nicht erneut gefragt: Es wird angewendet, und das of_move_node, das fragte, gibt dann -5 zurück; ein anderer Knoten wird wie gewohnt gefragt. Standard: TRUE
ue_node_moved (string as_keys, string as_old_keys, long al_position)Ein Knoten hat sich mit seinem Teilbaum bewegt: ein Ziehen des Benutzers oder of_move_node. as_keys ist seine neue Adresse, as_old_keys die, die er hatte, al_position sein Platz unter seinem neuen Elternknoten (ab 1 gezählt). Die an der alten Adresse geholten Handles sind bereits freigegeben (of_move_node gibt sie sofort frei, ein Ziehen vor diesem Ereignis); ein an der neuen geholter Handle bleibt gültig
ue_sort_changed (string as_column, string as_dir, string as_sort)Die Sortierung hat sich geändert: ein Klick auf eine Kopfzeile oder of_sort. as_column ist ihr erster Schlüssel ("" für den Text der Knoten), as_dir seine Richtung (eine der SORT_-Konstanten), as_sort die ganze Sortierung, so geschrieben, wie das SetSort eines DataWindows sie liest ("type A, text D", "" ohne Sortierung). Das Entfernen der sortierten Spalte löst es mit dem nächsten Schlüssel der Sortierung aus, SORT_NONE, wenn es der einzige war
ue_layout_changed (string as_layout_json)Das Layout hat sich geändert: Breite oder Reihenfolge einer Spalte, Sortierung, ein geöffneter oder geschlossener Knoten oder of_set_layout. as_layout_json ist das ganze Layout, wie of_get_layout es liefert. Eine von Ihrem Code geschriebene Breite, ein Platz oder eine Sichtbarkeit einer Spalte löst es ebenfalls aus, wenn sich das Layout ändert; Titel, Format, Ausrichtung, Sortiererlaubnis und Gesamtwert bleiben stumm
ue_write_back_failed (string as_keys, string as_col, string as_value, string as_reason)ib_write_back: Der DataStore hat einen Wert abgelehnt (ein Typ, den er nicht aufnehmen kann, eine seit dem Laden gelöschte Zeile), oder es gibt keinen DataStore mehr (as_reason = no DataStore is bound). Der Knoten ist zurückgekehrt (as_keys ist die Adresse, die er wieder hat); das Ereignis der Geste wird nicht ausgelöst. as_reason sagt auch, wenn das Los des Knotens für einen anderen Knoten neu geladen wurde oder wenn die Hakenspalte Werte enthält, die weder ein Ja noch ein Nein sind
ue_image_failed (string as_keys, string as_reason)Das Bild eines Knotens konnte nicht angezeigt werden: as_reason ist REASON_INSECURE (eine http://-Adresse), REASON_UNC (ein Netzwerkpfad aus einer DataStore-Spalte) oder REASON_NOT_FOUND (Datei nicht gefunden). Einmal pro Knoten und Bild gemeldet
ue_selection_changing (string as_from_keys_json, string as_keys_json) → booleanAbbrechbar, bevor der Benutzer eine andere Auswahl wählt (ein Klick, die Tastatur, F3) und vor of_select_node, of_clear_selection, of_search_next / of_search_prev gefragt, nur wenn ib_veto_selection = true. as_from_keys_json ist die aktuelle Auswahl, as_keys_json die gewünschte (JSON-Arrays von Adressen). FALSE zurückzugeben lehnt ab: Nichts bewegt sich, nicht einmal der Tastaturfokus, und die Methode gibt -4 zurück. Was als Folge die Auswahl verlässt (geschlossener Zweig, Entfernen, Ausblenden, Suche), wird nicht gefragt. of_select_nodes fragt einmal für die ganze Auswahl. Um den Benutzer anderswohin zu führen, wählen Sie im Ereignis aus und geben dann FALSE zurück: Eine im Ereignis getroffene Auswahl wird nicht erneut gefragt. Standard: TRUE
ue_node_toggling (string as_keys, boolean ab_expanding) → booleanAbbrechbar, bevor ein Knoten sich öffnet (ab_expanding = true) oder schließt gefragt, nur wenn ib_veto_toggle = true: eine Geste (Chevron, Doppelklick, Tastatur, *, Symbolleiste, ein Zweig unter einem Ziehen) und Ihr Code (ib_expanded, of_expand_all, of_collapse_all, of_expand_to_level — eine Frage pro Knoten —, of_select_node und of_scroll_to_node für die Knoten, die sie öffnen). FALSE zurückzugeben lehnt ab: Der Knoten bleibt, wie er ist, und eine Methode gibt -4 zurück. Die Geschwister, die ib_single_expand schließt, werden nicht gefragt. Standard: TRUE. of_clear_children schließt, ohne zu fragen
ue_delete_requested (string as_keys_json)Der Benutzer hat Entf gedrückt: as_keys_json ist das JSON-Array der ausgewählten Knoten (in SELECT_NONE des Knotens mit dem Fokus; ohne Auswahl sonst wird nichts ausgelöst), weder ausgegraut noch schreibgeschützt. Der Baum entfernt nichts: Rufen Sie of_remove_node für das auf, was Ihre Anwendung löscht
ue_copy (string as_tsv)Der Benutzer hat Strg+C (oder Strg+Einfg) gedrückt: as_tsv enthält die ausgewählten Knoten (in SELECT_NONE den mit dem Fokus; ohne Auswahl sonst wird nichts ausgelöst) in der Reihenfolge des Baums, einen pro Zeile, den Text nach so vielen Tabulatoren wie seine Tiefe, dann die Spalten einer Baumliste ausgerichtet (zuerst eine Kopfzeile), eine Zahl roh (ein Punkt, weder Gruppierung noch Symbol). Der Baum versucht auch die Zwischenablage des Browsers, die einer Seite verweigert werden kann: ClipBoard(as_tsv), um sicher zu sein
ue_drop_files (string as_keys, string as_files[])Aus dem Explorer wurden Dateien auf einen Knoten abgelegt (ib_allow_drop): as_keys ist die Adresse des Knotens unter dem Cursor — leer bei einem Ablegen neben den Knoten, auf einem ausgegrauten Knoten oder auf einem Knoten, dessen ib_drop_target false ist —, as_files die vollständigen Pfade
ue_state_clicked (string as_keys)Der Benutzer hat das Statusbild eines Knotens angeklickt (is_state_image): eine Flagge, ein Status, den Ihre Anwendung ein- und ausschaltet. Der Knoten wird nicht ausgewählt, wie bei seinem Kästchen; ein ausgegrauter Knoten löst nichts aus. Nur bei einer Geste ausgelöst
ue_csv_saved (string as_path, boolean ab_ok, string as_error)Die von of_export_csv angeforderte CSV-Datei wurde geschrieben (ab_ok = true) — oder nicht: as_error sagt warum (der Demomodus, ein nicht beschreibbarer Pfad). as_path ist der geschriebene Pfad, ein relativer aufgelöst
ue_xlsx_saved (string as_path, boolean ab_ok, string as_error)Die von of_export_xlsx angeforderte Arbeitsmappe wurde geschrieben (ab_ok = true) — oder nicht: as_error sagt warum
ue_drag_enter ( )Ein Ziehen von Dateien aus dem Explorer ist in die Komponente gekommen (ib_allow_drop)
ue_drag_leave ( )Das Ziehen von Dateien ist ohne Ablegen wieder gegangen — ein Ablegen löst nur ue_drop_files aus
ue_ready ( )Die Komponente ist fertig geladen; alles zuvor Gesendete wurde nachgespielt
ue_runtime_missing ( )Die WebView2-Runtime fehlt: die Komponente bleibt leer
ue_bg_color (long al_color)Die Komponente hat ihre Design-Hintergrundfarbe berechnet; das Userobject hat sie bereits übernommen (backcolor)

Tastatur und Maus #


Beispiele #

Anzuhakende Rechte #

// The rights of a role : a module, then what it allows
uo_rights.ib_checkboxes = true
uo_rights.of_add_node(/*keys*/ "sales", /*text*/ "Sales")
uo_rights.of_add_node(/*keys*/ "sales/read", /*text*/ "Read orders")
uo_rights.of_add_node(/*keys*/ "sales/write", /*text*/ "Create and change orders")
uo_rights.of_add_node(/*keys*/ "sales/delete", /*text*/ "Delete orders")

// What the role already has ; Sales shows mixed
uo_rights.of_node(/*keys*/ "sales/read").ib_checked = true
uo_rights.of_node(/*keys*/ "sales").ib_expanded = true
// event ue_node_checked of uo_rights : (string as_keys, boolean ab_checked)
// Delete never without write : checking it checks write too
if as_keys = "sales/delete" and ab_checked then this.of_node(/*keys*/ "sales/write").ib_checked = true

Das Layout beim nächsten Start wiederfinden #

// event ue_layout_changed of uo_tree : (string as_layout_json)
// Widths, order, sort and open nodes, kept for the next start
// (the nodes need STABLE keys : a ROLE_KEY column, never the RowIDs a new Retrieve gives)
SetProfileString("app.ini", "tree", "layout", as_layout_json)
// Local variables
string ls_layout

// After the tree is filled : the layout of the last time, if there is one
ls_layout = ProfileString("app.ini", "tree", "layout", "")
if ls_layout <> "" then uo_tree.of_set_layout(/*layout_json*/ ls_layout)

Ein Menü auf einem Knoten #

// The entries of the menu, once : uo_menu is a contextmenu of the window, and
// is_menu_keys a string instance variable that keeps the node right-clicked
uo_menu.of_add_item(/*keys*/ "expand", /*text*/ "Expand")
uo_menu.of_add_item(/*keys*/ "delete", /*text*/ "Delete")
// event ue_node_rclicked of uo_tree : (string as_keys, long al_x, long al_y)
// The node clicked is kept : the selection may have stayed elsewhere (a veto that
// refused it, SELECT_NONE). The menu opens where the user clicked
is_menu_keys = as_keys
uo_menu.of_show(/*x*/ al_x, /*y*/ al_y)
// event ue_item_selected of uo_menu : (string as_keys)
// The entry chosen acts on the node right-clicked
choose case as_keys
    case "expand"
        uo_tree.of_node(/*keys*/ is_menu_keys).ib_expanded = true
    case "delete"
        uo_tree.of_remove_node(/*keys*/ is_menu_keys)
end choose

Bewährte Praxis #

Vom gemeinsamen Sockel geerbt #

Diese Mitglieder gibt es bei jeder visuellen Komponente — sie sind nicht dieser eigen. Sie werden einmal in den übergreifenden Kapiteln beschrieben; diese Tabelle sagt nur, wo man sie liest.

MitgliederRolleBeschrieben in
of_count · of_keys_at · of_hasDurchlaufen, was die Komponente enthält3.2 Die Items
of_resetDie Komponente zurücksetzen3.6 Eine Komponente zurücksetzen: of_reset()
of_register_shortcut · of_clear_shortcutsTastenkürzel der Komponente3.5 Tastenkombinationen
of_is_created · of_is_ready · of_get_last_errorOb sie entstanden ist, ob sie bereit ist, was fehlschlug3.7 Diagnose
of_save_as_png · of_save_as_jpgDie Darstellung als Bild exportieren3.8 Die Darstellung als Bild exportieren
of_set_redrawÄnderungen zu einem einzigen Neuzeichnen bündeln3.10 Best Practices
of_preload_iconsSymbole ohne VerzögerungSofortige Anzeige: of_icon
of_set_translationEine Beschriftung der Komponente übersetzen5.2 Eine Beschriftung anpassen: of_set_translation
of_focus_webviewDer Komponente den Fokus geben6.4 Tastatur und Fokus
of_print · of_print_to_pdfDrucken oder ein PDF schreiben6.9 Drucken
of_set_property · of_get_property · of_component_nameEine Eigenschaft über ihren Namen steuern3.1 Die Eigenschaften-Engine
is_accessible_name · is_accessible_descriptionName und Beschreibung, die ein Bildschirmleser sagt3.4 Optionale Eigenschaften und Events

Zwei Helfer werden nicht geerbt: of_icon und of_escape_markup liegen auf n_pbt_utils. Deklarieren Sie eines — n_pbt_utils lnv_utils, nichts zu erzeugen — und rufen Sie sie darauf auf.

← Komponentenreferenz · Inhalt des Handbuchs