TOC

This article has been localized into German by the community.

Das TreeView Steuerelement:

TreeView mit verzögertem Laden der Elemente

Der übliche Prozess bei der Verwendung der TreeView ist es, sich an eine Sammlung von Elementen zu binden oder jede Ebene gleichzeitig manuell hinzuzufügen. In einigen Situationen möchten Sie jedoch das Laden von untergeordneten Elementen eines Knoten verzögern, bis sie tatsächlich benötigt werden. Dies ist besonders nützlich, wenn Sie einen sehr tiefen Baum mit vielen Ebenen und Unterknoten haben und ein gutes Beispiel dafür ist die Ordnerstruktur Ihres Windows-Computers.

Jedes Laufwerk auf Ihrem Windows-Computer hat eine Reihe von Unterordnern, und jeder dieser Unterordner hat wiederum Unterordner unter sich und so weiter. Das Durchlaufen jedes Laufwerks und all seiner Unterordner wäre extrem zeitaufwändig, und Ihre TreeView würde bald aus vielen Knoten bestehen, von denen die wenigsten je benötigt würden. Dies ist die perfekte Aufgabe für eine verzögert ladende geladene TreeView, bei der Unterordner nur bei Bedarf geladen werden.

Um dies zu erreichen, fügen wir einfach einen Dummy-Ordner zu jedem Laufwerk oder Unterordner hinzu, und wenn der Benutzer ihn erweitert, entfernen wir den Dummy-Ordner und ersetzen ihn durch die tatsächlichen Werte. So sieht unsere Anwendung beim Start aus - zu diesem Zeitpunkt haben wir nur eine Liste der verfügbaren Laufwerke auf dem Computer erhalten:

Sie können nun mit dem Erweitern der Knoten beginnen, und die Anwendung lädt automatisch die Unterordner. Wenn ein Ordner leer ist, wird er beim Versuch, ihn zu erweitern, als leer angezeigt, wie er auf dem nächsten Screenshot zu sehen ist:

Wie wird es das erreicht? Werfen wir einen Blick auf den Code:

<Window x:Class="WpfTutorialSamples.TreeView_control.LazyLoadingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="LazyLoadingSample" Height="300" Width="300">
    <Grid>
        <TreeView Name="trvStructure" TreeViewItem.Expanded="TreeViewItem_Expanded" Margin="10" />
    </Grid>
</Window>
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;

namespace WpfTutorialSamples.TreeView_control
{
	public partial class LazyLoadingSample : Window
	{
		public LazyLoadingSample()
		{
			InitializeComponent();
			DriveInfo[] drives = DriveInfo.GetDrives();
			foreach(DriveInfo driveInfo in drives)
				trvStructure.Items.Add(CreateTreeItem(driveInfo));
		}

		public void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
		{
			TreeViewItem item = e.Source as TreeViewItem;
			if((item.Items.Count == 1) && (item.Items[0] is string))
			{
				item.Items.Clear();

				DirectoryInfo expandedDir = null;
				if(item.Tag is DriveInfo)
					expandedDir = (item.Tag as DriveInfo).RootDirectory;
				if(item.Tag is DirectoryInfo)
					expandedDir = (item.Tag as DirectoryInfo);
				try
				{
					foreach(DirectoryInfo subDir in expandedDir.GetDirectories())
						item.Items.Add(CreateTreeItem(subDir));
				}
				catch { }
			}
		}

		private TreeViewItem CreateTreeItem(object o)
		{
			TreeViewItem item = new TreeViewItem();
			item.Header = o.ToString();
			item.Tag = o;
			item.Items.Add("Loading...");
			return item;
		}
	}
}

Das XAML ist sehr einfach und nur ein interessantes Detail ist vorhanden: Die Art und Weise, wie wir das Ereignis "Expanded" von TreeViewItem abonnieren. Beachten Sie, dass dies tatsächlich das TreeViewItem und nicht die TreeView selbst ist, aber da das Ereignis sich nach oben ausbreitet, können wir es einfach an einer Stelle für die gesamte TreeView erfassen, anstatt es für jedes Element, das wir dem Baum hinzufügen, abonnieren zu müssen. Dieses Ereignis wird jedes Mal aufgerufen, wenn ein Element erweitert wird, was wir beachten müssen, um seine untergeordneten Elemente bei Bedarf zu laden.

In Code-behind beginnen wir damit, jedes auf dem Computer gefundene Laufwerk zum TreeView-Control hinzuzufügen. Wir weisen die DriveInfo-Instanz der Tag-Eigenschaft zu, damit wir sie später wieder abrufen können. Beachten Sie, dass wir eine benutzerdefinierte Methode zum Erstellen des TreeViewItem verwenden: CreateTreeItem(), da wir genau die gleiche Methode verwenden können, wenn wir später dynamisch einen Unterordner hinzufügen möchten. Beachten Sie bei dieser Methode, wie wir ein untergeordnetes Element in Form einer Zeichenkette mit dem Text "Loading...." zur Element-Collection hinzufügen.

Als nächstes kommt das Ereignis TreeViewItem_Expanded. Wie bereits erwähnt, wird dieses Ereignis jedes Mal ausgelöst, wenn ein TreeView-Element erweitert wird, so dass wir zunächst prüfen, ob dieses Element bereits geladen wurde, indem wir prüfen, ob die untergeordneten Elemente derzeit nur aus einem Element bestehen, das eine Zeichenkette ist - wenn ja, haben wir das untergeordnete Element "Laden...." gefunden, was bedeutet, dass wir nun den eigentlichen Inhalt laden und das Platzhalter-Element durch dieses ersetzen sollten.

Wir verwenden nun die Tag-Eigenschaft der Elemente, um einen Verweis auf die DriveInfo- oder DirectoryInfo-Instanz zu erhalten, die das aktuelle Element repräsentiert, und dann erhalten wir eine Liste von Unterverzeichnissen, die wir dem angeklickten Element hinzufügen, wiederum mit der CreateTreeItem()-Methode. Beachten Sie, dass die Schleife, in der wir jeden Unterordner hinzufügen, in einem Try..catch block ist - dies ist wichtig, da einige Pfade möglicherweise nicht zugänglich sind, normalerweise aus Sicherheitsgründen. Sie könnten die Ausnahme abfangen und damit in der einen oder anderen Weise auf der Benutzeroberfläche wiedergeben.

Zusammenfassung

Wenn wir das Expanded-Ereignis abonnieren, können wir ganz einfach eine verzögernd landende TreeView erstellen, die in vielen Fällen die bessere Lösung sein wird.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!