Registerkartenansicht
Das TabView-Steuerelement bietet eine Möglichkeit, eine Reihe von Registerkarten und deren jeweiligen Inhalt anzuzeigen. TabView-Steuerelemente sind nützlich, um mehrere Seiten (oder Dokumente) von Inhalten anzuzeigen, während ein Benutzer neue Registerkarten neu anordnen, schließen oder öffnen kann.
Ist dies das richtige Steuerelement?
Allgemein gibt es zwei verschiedene Arten von Registerkarten, die sich in Funktion und Aussehen unterscheiden:
- Statische Registerkarten sind die Art von Registerkarten, die häufig in Einstellungsfenstern zu finden sind. Sie enthalten eine festgelegte Anzahl von Seiten in einer festgelegten Reihenfolge, die in der Regel vordefinierte Inhalte enthalten.
- Dokumentregisterkarten sind die Arten von Registerkarten, die in einem Browser enthalten sind, z.B. in Microsoft Edge. Benutzer können Registerkarten erstellen, entfernen und neu anordnen, Registerkarten zwischen Fenstern verschieben und den Inhalt von Registerkarten ändern.
Standardmäßig ist TabView so konfiguriert, dass es Dokumentregisterkarten bereitstellt. Wir empfehlen TabView, wenn Benutzer folgende Möglichkeiten haben:
- Registerkarten dynamisch öffnen, schließen oder neu anordnen.
- Öffnen Sie Dokumente oder Webseiten direkt in Registerkarten.
- Ziehen und Ablegen von Registerkarten zwischen Fenstern.
Die TabView API bietet die Möglichkeit, das Steuerelement für statische Registerkarten zu konfigurieren. Um der Anleitung des Windows Designers zu folgen und wenn es mehr als ein paar statische Navigationselemente gibt, sollten Sie jedoch ein NavigationView Steuerelement verwenden.
Aufbau
Eine mit Registerkarten versehene Benutzeroberfläche wird mit einem TabView-Steuerelement und einem oder mehreren TabViewItem-Steuerelementen erstellt. Die TabView enthält Instanzen von TabViewItem, die eine einzelne Registerkarte und deren Inhalt darstellen.
TabView Elemente
Dieses Bild zeigt die Elemente des TabView Steuerelements. Der Tab-Strip hat eine Kopf- und eine Fußzeile, aber im Gegensatz zu einem Dokument befinden sich die Kopf- und die Fußzeile des Tab-Strips ganz links bzw. ganz rechts im Strip.
TabViewItem Elemente
Dieses Bild zeigt die Elemente des TabViewItem Steuerelements. Obwohl der Inhalt innerhalb des TabView-Steuerelements angezeigt wird, ist der Inhalt eigentlich ein Element von TabViewItem.
Empfehlungen
Registerkartenauswahl
Die meisten Benutzer sind mit der Verwendung von Dokumentregisterkarten einfach deshalb vertraut, weil sie einen Webbrowser verwenden. Wenn sie Dokumentregisterkarten in Ihrer App verwenden, steuert ihre Erfahrung ihre Erwartungen, wie sich die Registerkarten verhalten sollten.
Unabhängig davon, wie der Benutzer mit einer Reihe von Dokumentregisterkarten interagiert, sollte immer eine aktive Registerkarte vorhanden sein. Wenn der Benutzer die ausgewählte Registerkarte schließt oder in ein anderes Fenster aufteilt, sollte eine andere Registerkarte zur aktiven Registerkarte werden. TabView versucht dies, indem es automatisch die nächste Registerkarte auswählt. Wenn es einen guten Grund dafür gibt, dass Ihre App eine TabView mit einer nicht ausgewählten Registerkarte zulassen sollte, bleibt der Inhaltsbereich der TabView einfach leer.
Tastaturnavigation
TabView unterstützt standardmäßig viele gängige Navigationsszenarien mit der Tastatur. In diesem Abschnitt werden die integrierten Funktionen erläutert und Empfehlungen für zusätzliche Funktionen gegeben, die für einige Apps hilfreich sein können.
Verhalten der TAB- und CURSORTASTEN
Wenn der Fokus in den TabStrip-Bereich bewegt wird, erhält das ausgewählte TabViewItem den Fokus. Der Benutzer kann dann mit den Pfeiltasten Links und Rechts den Fokus (nicht die Auswahl) auf andere Registerkarten im Tab-Strip verschieben. Der Pfeiltastenfokus ist im TabStrip-Element und in der Schaltfläche zum Hinzufügen von Registerkarten „(+)“ eingeschlossen, falls vorhanden. Um den Fokus außerhalb des Tab-Bereichs zu verschieben, kann der Benutzer die Tab--Taste drücken, wodurch der Fokus auf das nächste fokussierbare Element verschoben wird.
Fokus über Tab verschieben
Pfeiltasten führen keine Fokusrotation aus
Auswählen einer Registerkarte
Wenn ein TabViewItem den Fokus hat, drücken Sie Leertaste oder Eingabe, um dieses TabViewItem auszuwählen.
Verwenden Sie die Pfeiltasten, um den Fokus zu verschieben, und drücken Sie dann Leertaste, um eine Registerkarte auszuwählen.
Tastenkombinationen zum Auswählen angrenzender Registerkarten
Drücken Sie Strg+Tab, um die nächste TabViewItem auszuwählen. Drücken Sie Strg+Umschalt+Tab, um die vorherige Registerkarte auszuwählen. Wenn Sie also die nächste Registerkarte auswählen, während die letzte Registerkarte ausgewählt ist, wird die erste Registerkarte ausgewählt.
Schließen einer Registerkarte
Drücken Sie Strg + F4, um das Ereignis TabCloseRequested auszulösen. Behandeln Sie das Ereignis, und schließen Sie gegebenenfalls die Registerkarte.
Tipp
Weitere Informationen finden Sie unter Tastaturanleitung für Entwickler weiter unten in diesem Artikel.
Erstellen einer Registerkartenansicht
- Wichtige APIs: TabView-Klasse, TabViewItem-Klasse
Die WinUI 3 Gallery App enthält interaktive Beispiele für die meisten WinUI 3-Steuerelemente, -Features und -Funktionen. Laden Sie die App aus dem Microsoft Store herunter, oder rufen Sie den Quellcode auf GitHub ab
Die Beispiele in diesem Abschnitt zeigen eine Vielzahl von Möglichkeiten, ein TabView-Steuerelement zu konfigurieren.
Elemente der Registerkartenansicht
Jede Registerkarte in einer TabView wird durch ein TabViewItem-Steuerelement dargestellt, das sowohl die Registerkarte, die im Tab-Strip angezeigt wird, als auch den unterhalb des Tab-Strips angezeigten Inhalt enthält.
Konfigurieren einer Registerkarte
Für jedes TabViewItem-Objekt können Sie eine Kopfzeile und ein Symbol festlegen und angeben, ob der Benutzer die Registerkarte schließen kann.
- Die Eigenschaft Header wird normalerweise auf eine Zeichenfolge festgelegt, die eine beschreibende Kennzeichnung für die Registerkarte enthält. Die Eigenschaft
Header
kann jedoch ein beliebiges Objekt sein. Sie können auch die HeaderTemplate-Eigenschaft verwenden, um eine DataTemplate-Eigenschaft anzugeben, die definiert, wie gebundene Headerdaten angezeigt werden sollen. - Legen Sie die Eigenschaft IconSource fest, um ein Symbol für die Registerkarte zu bestimmen.
- Standardmäßig wird auf der Registerkarte eine Schaltfläche zum Schließen angezeigt. Sie können die Eigenschaft IsClosable auf
false
festlegen, um sicherzustellen, dass ein Benutzer die Registerkarte nicht schließen kann.
Für die TabView können Sie mehrere Optionen konfigurieren, die für alle Registerkarten gelten.
- Standardmäßig wird die Schaltfläche Schließen (X) bei schließbaren Registerkarten immer angezeigt. Sie können die Eigenschaft CloseButtonOverlayMode auf
OnPointerOver
festlegen, um dieses Verhalten zu ändern. In diesem Fall zeigt die ausgewählte Registerkarte immer die Schaltfläche „Schließen“ an, wenn sie schließbar ist, während nicht ausgewählte Registerkarten die Schaltfläche „Schließen“ nur anzeigen, wenn die Registerkarte schließbar ist und der Benutzer den Mauszeiger darüber bewegt. - Sie können die Eigenschaft TabWidthMode festlegen, um die Größe der Registerkarten zu ändern. (Die Eigenschaft
Width
wird beiTabViewItem
ignoriert.) Dies sind die Optionen in der Auflistung TabViewWidthMode:-
Equal
– Jede Registerkarte hat die gleiche Breite. Dies ist die Standardeinstellung. -
SizeToContent
– Jede Registerkarte passt ihre Breite an den Inhalt innerhalb der Registerkarte an. -
Compact
– Nicht ausgewählte Registerkarten werden eingeklappt und zeigen nur ihr Symbol. Die ausgewählte Registerkarte passt sich an den Bildschirm des Inhalts der Registerkarte an.
-
Inhalt
Die auf der ausgewählten Registerkarte angezeigten Elemente werden der Eigenschaft Inhalt des TabViewItem hinzugefügt. TabViewItem ist ein ContentControl, sodass Sie ein beliebiges Objekt als Inhalt hinzufügen können. Sie können auch ein DataTemplate auf die Eigenschaft ContentTemplate anwenden. Weitere Informationen finden Sie in der Klasse ContentControl.
Die Beispiele in diesem Artikel zeigen einen einfachen Fall, in dem Text direkt zum Content
-Element in XAML hinzugefügt wird. Echte UI ist jedoch in der Regel komplexer. Eine gängige Methode, komplexe Benutzeroberflächen als Inhalt einer Registerkarte hinzuzufügen, besteht darin, sie in einem UserControl oder einer Page zu kapseln und diese als Inhalt des TabViewItem hinzuzufügen. In diesem Beispiel wird davon ausgegangen, dass Ihre App über ein XAML-UserControl namens PictureSettingsControl
verfügt.
<TabViewItem>
<TabViewItem.Content>
<local:PictureSettingsControl/>
</TabViewItem.Content>
</TabViewItem>
Statische Registerkarten
Dieses Beispiel zeigt eine einfache TabView mit zwei statischen Registerkarten. Beide Registerkarten werden in XAML als Inhalt der TabView hinzugefügt.
Verwenden Sie die folgenden Einstellungen, um eine TabView statisch zu machen:
- Legen Sie die Eigenschaft IsAddTabButtonVisible auf
false
fest, um die Schaltfläche Registerkarte hinzufügen zu verbergen und zu verhindern, dass das Ereignis AddTabButtonClick ausgelöst wird. - Legen Sie die eigenschaft CanReorderTabs auf
false
fest, um zu verhindern, dass der Benutzer Registerkarten in eine andere Reihenfolge zieht. - Legen Sie bei jedem TabViewItem die Eigenschaft IsClosable auf false fest, um die Schaltfläche Registerkarte schließen zu verbergen und zu verhindern, dass der Benutzer das Ereignis TabCloseRequested auslöst.
<TabView VerticalAlignment="Stretch"
IsAddTabButtonVisible="False"
CanReorderTabs="False">
<TabViewItem Header="Picture" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Pictures"/>
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="Picture settings"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
<TabViewItem Header="Sound" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Audio"/>
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="Sound settings"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
</TabView>
Dokumentregisterkarten
Standardmäßig ist die TabView für Dokumentregisterkarten konfiguriert. Der Benutzer kann neue Registerkarten hinzufügen, Registerkarten neu anordnen und Registerkarten schließen. In dieser Konfiguration müssen Sie die Ereignisse AddTabButtonClick und TabCloseRequested behandeln, um die Funktionalität zu aktivieren.
Wenn einem TabView Registerkarten hinzugefügt werden, kann es sein, dass es irgendwann zu viele Registerkarten gibt, um sie in Ihrem Tab-Strip anzuzeigen. In diesem Fall werden Scroll Bumper angezeigt, mit denen der Benutzer den Tab-Strip nach links und rechts verschieben kann, um auf versteckte Registerkarten zuzugreifen.
Dieses Beispiel erstellt eine einfache TabView zusammen mit Ereignishandlern, um das Öffnen und Schließen von Registerkarten zu unterstützen. Der TabView_AddTabButtonClick
-Ereignishandler zeigt, wie ein TabViewItem-Objekt im Code hinzugefügt wird.
<TabView VerticalAlignment="Stretch"
AddTabButtonClick="TabView_AddTabButtonClick"
TabCloseRequested="TabView_TabCloseRequested">
<TabViewItem Header="Home" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Home" />
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="TabView content"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
</TabView>
// Add a new tab to the TabView.
private void TabView_AddTabButtonClick(TabView sender, object args)
{
var newTab = new TabViewItem();
newTab.Header = $"New Document {sender.TabItems.Count}";
newTab.IconSource = new SymbolIconSource() { Symbol = Symbol.Document };
newTab.Content = new TextBlock() { Text = $"Content for new tab {sender.TabItems.Count}.",
Padding = new Thickness(12) };
sender.TabItems.Add(newTab);
sender.SelectedItem = newTab;
}
// Remove the requested tab from the TabView.
private void TabView_TabCloseRequested(TabView sender,
TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
}
Schließen Sie das Fenster, wenn die letzte Registerkarte geschlossen wird
Wenn alle Registerkarten in Ihrer App geschlossen werden können und das Fenster Ihrer App geschlossen werden soll, wenn die letzte Registerkarte geschlossen wird, sollten Sie das Fenster auch im TabCloseRequested Event Handler schließen.
Fügen Sie zunächst in der Datei App.xaml.cs
eine öffentliche Eigenschaft hinzu, mit der Sie über die Page
, die die TabView hostet, auf die Window
Instanz zugreifen können.
public partial class App : Application
{
// ... code removed.
public Window? Window => m_window; // Add this.
private Window? m_window;
}
Ändern Sie dann den Ereignis-Handler TabCloseRequested, um Window.Close aufzurufen, wenn alle Registerkarten aus der TabView entfernt wurden.
// Remove the requested tab from the TabView.
// If all tabs have been removed, close the Window.
private void TabView_TabCloseRequested(TabView sender,
TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
if (sender.TabItems.Count == 0)
{
var window = (Application.Current as App)?.Window as MainWindow;
window?.Close();
}
}
Hinweis
Dieses Beispiel funktioniert für eine App mit einem einzelnen Fenster (MainWindow
). Wenn Ihre App mehrere Fenster hat oder Sie das Herausziehen von Registerkarten aktiviert haben, müssen Sie die Fenster verfolgen und dann das richtige Fenster zum Schließen finden. Ein Beispiel hierfür finden Sie im nächsten Abschnitt.
Tabstoppausriss
Tab-Strip Herausziehen beschreibt, was passiert, wenn ein Benutzer eine Registerkarte aus dem TabView Tab-Strip herauszieht und sie in ein anderes TabView-Steuerelement verschiebt, normalerweise in ein neues Fenster.
Ab Windows App SDK 1.6 verfügt TabView über eine CanTearOutTabs-Eigenschaft, die Sie festlegen können, um das Herausziehen von Registerkarten in ein neues Fenster zu erleichtern. Wenn ein Benutzer eine Registerkarte aus dem Tab-Strip herauszieht und diese Option aktiviert ist, wird während des Ziehens sofort ein neues Fenster erstellt, das dem Benutzer die Möglichkeit bietet, die Karte bis zum Rand des Bildschirms zu ziehen, um sie zu maximieren oder das Fenster mit einer fließenden Bewegung auszugleichen. Diese Implementierung verwendet auch keine Drag-and-Drop-APIs, sodass sie nicht durch Einschränkungen in diesen APIs beeinträchtigt wird.
Wenn Sie die Eigenschaft CanTearOutTabs auf true
festlegen, werden die Registerkarten-Herausziehen-Ereignisse anstelle der Drag-and-Drop-Ereignisse ausgelöst. Um das Herausziehen von Registerkarten zu implementieren, müssen Sie diese Ereignisse behandeln:
-
Dieses Ereignis tritt ein, wenn eine Registerkarte zum ersten Mal aus dem Tab-Strip herausgezogen wird. Behandeln Sie es, um ein neues Fenster und eine neue TabView zu erstellen, in die die Registerkarte verschoben werden soll.
-
Dieses Ereignis tritt auf, nachdem ein neues Fenster bereitgestellt wurde. Behandeln Sie es, um die herausgezogene Registerkarte aus der ursprünglichen TabView in eine TabView im neuen Fenster zu verschieben.
-
Dieses Ereignis tritt ein, wenn eine herausgezogene Registerkarte über eine bestehende TabView gezogen wird. Behandeln Sie es in der TabView, die die herausgezogene Registerkarte empfängt, um anzugeben, ob die Registerkarte akzeptiert werden soll oder nicht.
-
Dieses Ereignis tritt ein, wenn eine herausgezogene Registerkarte über eine bestehende TabView gezogen wird und das Ereignis
ExternalTornOutTabsDropping
anzeigt, dass das Herausziehen erlaubt ist. Behandeln Sie es in der TabView, die die herausgezogene Registerkarte empfängt, um die Registerkarte aus der ursprünglichen TabView zu entfernen und sie in die empfangende TabView am angegebenen Index einzufügen.
Diese Ereignisse werden nicht ausgelöst, wenn das Herausziehen von Registerkarten aktiviert ist: TabDragStarting, TabStripDragOver, TabStripDrop, TabDragCompleted, TabDroppedOutside.
Vorsicht
Tabstoppausriss wird in Prozessen unterstützt, die als Administrator ausgeführt werden.
Die folgenden Beispiele zeigen, wie Sie die Implementierung der Ereignis-Handler zur Unterstützung des Herausziehens von Registerkarten vornehmen.
TabView einrichten
Diese XAML legt die Eigenschaft CanTearOutTabs auf true
fest und richtet die Handler für das Herausziehen der Registerkarten ein.
<TabView x:Name="tabView"
CanTearOutTabs="True"
TabTearOutWindowRequested="TabView_TabTearOutWindowRequested"
TabTearOutRequested="TabView_TabTearOutRequested"
ExternalTornOutTabsDropping="TabView_ExternalTornOutTabsDropping"
ExternalTornOutTabsDropped="TabView_ExternalTornOutTabsDropped">
<!-- TabView content -->
</TabView>
Ein neues Fenster erstellen und verfolgen
Das Herausziehen von Registerkarten erfordert, dass Sie in Ihrer App neue Fenster erstellen und verwalten.
Tipp
Die WinUI Gallery-App enthält eine WindowHelper
Klasse, die die Verwaltung von Fenstern in Ihrer App erleichtert. Sie können es aus GitHub im WinUI Gallery-Repository kopieren: WindowHelper.cs. Wir empfehlen diese Hilfsklasse, um das Herausziehen von Registerkarten zu implementieren. Sehen Sie sich die TabViewWindowingSamplePage auf GitHub an, um zu sehen, wie sie verwendet wird.
In diesem Artikel werden die Hilfsmethoden von WindowHelper.cs
kopiert, aber zur besseren Lesbarkeit modifiziert und inline dargestellt.
Hier wird in App.xaml.cs
eine Liste zur Überwachung aller aktiven Fenster erstellt. Die OnLaunched
-Methode wird aktualisiert, um das Fenster nach seiner Erstellung nachzuverfolgen. (Dies ist nicht erforderlich, wenn Sie die WindowHelper
Klasse verwenden.)
static public List<Window> ActiveWindows = new List<Window>();
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
// Track this window.
ActiveWindows.Add(m_window);
m_window.Activate();
}
Wenn das Herausziehen der Registerkarte beginnt, wird ein neues Fenster angefordert. Hier bietet die Variable tabTearOutWindow
zugriff auf das neue Fenster, nachdem sie erstellt wurde. Die Hilfsmethoden CreateWindow
und TrackWindow
erstellen ein neues Fenster und fügen es der Liste der aktiven Fenster hinzu.
Nachdem Sie das neue Fenster erstellt haben, müssen Sie eine neue Seite erstellen und als Inhalt des Fensters festlegen. Die neue Seite muss ein TabView-Steuerelement enthalten, in das Sie die herausgezogene Registerkarte im TabTearOutRequested
Ereignis-Handler verschieben werden.
Tipp
In diesem Beispiel erstellen wir eine neue MainPage
-Klasse, da sie nur eine leere TabView enthält (es werden keine Registerkarten direkt in XAML hinzugefügt). Wenn MainPage
andere UI-Elemente enthält, die nicht im herausgelösten Fenster angezeigt werden sollen, können Sie eine separate Seite erstellen, die nur Elemente enthält, die Sie benötigen (einschließlich mindestens einer TabView), und eine Instanz dieser Seite erstellen.
Weisen Sie schließlich die AppWindow.Id des neuen Fensters der Eigenschaft args.
NewWindowId zu. Diese wird in der Eigenschaft TabViewTabTearOutRequestedEventArgs.NewWindowId verwendet, damit Sie von diesem Ereignis Handler aus auf das Fenster zugreifen können.
private Window? tabTearOutWindow = null;
private void TabView_TabTearOutWindowRequested(TabView sender, TabViewTabTearOutWindowRequestedEventArgs args)
{
tabTearOutWindow = CreateWindow();
tabTearOutWindow.Content = new MainPage();
// Optional window setup, such as setting the icon or
// extending content into the title bar happens here.
args.NewWindowId = tabTearOutWindow.AppWindow.Id;
}
private Window CreateWindow()
{
Window newWindow = new Window
{
SystemBackdrop = new MicaBackdrop()
};
newWindow.Title = "Torn Out Window";
TrackWindow(newWindow);
return newWindow;
}
private void TrackWindow(Window window)
{
window.Closed += (sender, args) => {
App.ActiveWindows.Remove(window);
};
App.ActiveWindows.Add(window);
}
Schließe ein Fenster, wenn der letzte Tab geschlossen wird.
Wie bereits erwähnt, möchten Sie vielleicht das Fenster schließen, wenn die letzte Registerkarte in einer TabView geschlossen wird. Wenn Ihre App über mehrere Fenster verfügt, müssen Sie das richtige Fenster in Ihrer Liste der verfolgten Fenster finden, um es zu schließen. In diesem Beispiel wird gezeigt, wie das geht.
// Remove the requested tab from the TabView.
// If all tabs have been removed, close the Window.
private void TabView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
if (sender.TabItems.Count == 0)
{
GetWindowForElement(this)?.Close();
}
}
public Window? GetWindowForElement(UIElement element)
{
if (element.XamlRoot != null)
{
foreach (Window window in App.ActiveWindows)
{
if (element.XamlRoot == window.Content.XamlRoot)
{
return window;
}
}
}
return null;
}
Verschieben der Registerkarte in das neue Fenster
Nachdem das neue Fenster bereitgestellt wurde, müssen Sie die herausgezogene Registerkarte aus der sender
TabView entfernen und sie der TabView im neuen Fenster hinzufügen. In diesem Beispiel können Sie mit der public AddTabToTabs
-Hilfsmethode von der ursprünglichen Seiteninstanz aus auf die TabView in der neuen MainPage
-Instanz zugreifen, um ihr die herausgerissene Registerkarte hinzuzufügen.
private void TabView_TabTearOutRequested(TabView sender, TabViewTabTearOutRequestedEventArgs args)
{
if (tabTearOutWindow?.Content is MainPage newPage
&& args.Tabs.FirstOrDefault() is TabViewItem tab)
{
sender.TabItems.Remove(tab);
newPage.AddTabToTabs(tab);
}
}
// This method provides access to the TabView from
// another page instance so you can add the torn-out tab.
public void AddTabToTabs(TabViewItem tab)
{
tabView.TabItems.Add(tab);
}
Eine herausgezogene Registerkarte auf eine andere TabView ziehen
Wenn eine Registerkarte herausgezogen und in einem neuen Fenster platziert wurde, wie in den vorangegangenen Schritten gezeigt, kann eines von zwei Dingen passieren:
- Der Benutzer kann die Registerkarte loslassen und sie bleibt im neuen Fenster. Der Prozess des Herausziehens endet hier und es werden keine weiteren Ereignisse ausgelöst.
- Der Benutzende kann die herausgezogene Registerkarte wieder auf ein vorhandenes TabView-Steuerelement ziehen. In diesem Fall wird der Prozess fortgesetzt, und es werden mehrere weitere Ereignisse ausgelöst, damit Sie die Registerkarte aus der ursprünglichen TabView entfernen und die externe Registerkarte in eine vorhandene TabView einfügen können.
Wenn die Registerkarte über die bestehende TabView gezogen wird, wird das Ereignis ExternalTornOutTabsDropping ausgelöst. Im Handler des Ereignisses können Sie festlegen, ob das Einfügen der Registerkarte in diese TabView zulässig ist. In den meisten Fällen müssen Sie nur die Eigenschaft args.
AllowDrop auf true
festlegen. Wenn Sie jedoch vor dem Festlegen dieser Eigenschaft irgendwelche Prüfungen durchführen müssen, können Sie dies hier tun. Wenn AllowDrop
auf false
festgelegt ist, wird die Aktion zum Ziehen der Registerkarte fortgesetzt und das Ereignis ExternalTornOutTabsDropped wird nicht ausgelöst.
private void TabView_ExternalTornOutTabsDropping(TabView sender,
TabViewExternalTornOutTabsDroppingEventArgs args)
{
args.AllowDrop = true;
}
Wenn AllowDrop
im ExternalTornOutTabsDropping
-Ereignishandler auf true
festgelegt ist, wird das ExternalTornOutTabsDropped
-Ereignis sofort ausgelöst.
Hinweis
Das Dropped
im Namen des Ereignisses entspricht nicht direkt der Idee einer Drop-Aktion in den Drag&Drop-APIs. Hier muss der Benutzer die Registerkarte nicht loslassen, um eine Drop-Aktion durchzuführen. Das Ereignis wird ausgelöst, während die Registerkarte über dem Tab-Strip gehalten wird, und der Code wird ausgeführt, um die Registerkarte per Drop in die TabView zu ziehen.
Der Handler für das Ereignis ExternalTornOutTabsDropped folgt dem gleichen Strukturieren wie das Ereignis TabTearOutRequested, allerdings in umgekehrter Reihenfolge: Sie müssen die Registerkarte aus der ursprünglichen TabView entfernen und sie in die sender
TabView einfügen.
Das sender
TabView ist das Steuerelement, in das die Registerkarte eingefügt wird. Wir verwenden also die GetParentTabView
Hilfsmethode, um die ursprüngliche Registerkarte zu finden. Sie beginnt mit dem herausgezogenen TabViewItem und verwendet VisualTreeHelper, um den visuellen Baum nach oben zu gehen und die TabView zu finden, zu der das Element gehört. Nachdem die TabView gefunden wurde, wird das TabViewItem aus seiner TabItems Sammlung entfernt und in die sender
TabView's TabItems
Sammlung an dem durch args.
DropIndex angegebenen Index eingefügt.
private void TabView_ExternalTornOutTabsDropped(TabView sender,
TabViewExternalTornOutTabsDroppedEventArgs args)
{
if (args.Tabs.FirstOrDefault() is TabViewItem tab)
{
GetParentTabView(tab)?.TabItems.Remove(tab);
sender.TabItems.Insert(args.DropIndex, tab);
}
}
// Starting with the TabViewItem, walk up the
// visual tree until you get to the TabView.
private TabView? GetParentTabView(TabViewItem tab)
{
DependencyObject current = tab;
while (current != null)
{
if (current is TabView tabView)
{
return tabView;
}
current = VisualTreeHelper.GetParent(current);
}
return null;
}
Tipp
Wenn Sie das Windows Community Toolkit verwenden, können Sie die FindAscendant
Hilfsmethode in DependencyObjectExtensions des Toolkits anstelle von GetParentTabView
verwenden.
TabView Registerkarten in der Titelleiste eines Fensters anzeigen
Anstatt dass Tabs ihre eigene Zeile unterhalb der Titelleiste eines Fensters einnehmen, können Sie die beiden in denselben Bereich zusammenführen. Dies spart vertikalen Platz für Ihre Inhalte und verleiht Ihrer App ein modernes Erscheinungsbild.
Da ein Benutzer ein Fenster an seiner Titelleiste ziehen kann, um es neu zu positionieren, ist es wichtig, dass die Titelleiste nicht vollständig mit Registerkarten gefüllt ist. Wenn Sie Registerkarten in einer Titelleiste anzeigen, müssen Sie daher einen Teil der Titelleiste als ziehbaren Bereich reservieren. Wenn Sie keine verschiebbare Region angeben, ist die gesamte Titelleiste verschiebbar, sodass Ihre Registerkarten keine Eingabeereignisse empfangen können. Wenn Ihre TabView in der Titelleiste eines Fensters angezeigt wird, sollten Sie immer einen TabStripFooter in Ihre TabView einfügen und ihn als ziehbare Region markieren.
Weitere Informationen finden Sie unter Anpassen der Titelleiste.
<TabView VerticalAlignment="Stretch">
<TabViewItem Header="Home" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Home" />
</TabViewItem.IconSource>
</TabViewItem>
<TabView.TabStripFooter>
<Grid x:Name="CustomDragRegion" Background="Transparent" />
</TabView.TabStripFooter>
</TabView>
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var currentWindow = (Application.Current as App)?.Window as MainWindow;
currentWindow.ExtendsContentIntoTitleBar = true;
currentWindow.SetTitleBar(CustomDragRegion);
CustomDragRegion.MinWidth = 188;
}
Hinweis
Wie Sie eine Referenz auf das Fenster (currentWindow
) erhalten, hängt davon ab, wie Sie Fenster in Ihrer App verfolgen. Weitere Informationen finden Sie unter "Fenster schließen, wenn die letzte Registerkarte geschlossen wird" und "Ein neues Fenster erstellen und nachverfolgen" in diesem Artikel.
Tastaturanleitungen für Entwickler
Tipp
Weitere Informationen zur integrierten Tastaturunterstützung finden Sie unter Tastaturnavigation weiter oben in diesem Artikel.
Einige Anwendungen erfordern möglicherweise eine erweiterte Tastatursteuerung. Erwägen Sie, die folgenden Tastenkombinationen zu implementieren, wenn sie für Ihre Anwendung geeignet sind.
Warnung
Wenn Sie einer vorhandenen Anwendung eine TabView hinzufügen, haben Sie möglicherweise bereits Tastenkombinationen erstellt, die den Tastenkombinationen der empfohlenen TabView-Tastenkombinationen zugeordnet sind. In diesem Fall müssen Sie sich überlegen, ob Sie Ihre vorhandenen Tastenkombinationen beibehalten oder dem Benutzer eine intuitive Registerkarten-Benutzeroberfläche bieten möchten.
- Strg + T sollte eine neue Registerkarte öffnen. In der Regel wird diese Registerkarte mit einem vordefinierten Dokument gefüllt oder leer erstellt, wobei Sie den Inhalt einfach auswählen können. Wenn der Benutzer Inhalte für eine neue Registerkarte auswählen muss, sollte das Steuerelement für die Inhaltsauswahl den Eingabefokus besitzen.
- Strg + W sollte die ausgewählte Registerkarte schließen. Denken Sie daran, dass TabView automatisch die nächste Registerkarte auswählt.
- Strg + Umschalt + T öffnet kürzlich geschlossene Registerkarten (oder korrekter gesagt, öffnet neue Registerkarten mit demselben Inhalt wie die kürzlich geschlossenen Registerkarten). Beginnen Sie mit der zuletzt geschlossenen Registerkarte, und bewegen Sie sich für jeden nachfolgenden Aufruf der Tastenkombination rückwärts. Beachten Sie, dass hierfür eine Liste der zuletzt geschlossenen Registerkarten verwaltet werden muss.
- Strg + 1 sollte die erste Registerkarte in der Registerkartenliste auswählen. Analog dazu sollte STRG+2 die zweite Registerkarte auswählen, STRG+3 die dritte usw. bis STRG+8.
- Ctrl + 9 sollte den letzten Tab in der Tab-Liste auswählen, unabhängig davon, wie viele Tabs sich in der Liste befinden.
- Wenn Registerkarten mehr als nur den Befehl „Schließen“ bieten (z.B. Duplizieren oder Anheften einer Registerkarte), verwenden Sie ein Kontextmenü, um alle verfügbaren Aktionen anzuzeigen, die für eine Registerkarte ausgeführt werden können.
Implementieren von Tasaturverhalten im Browserstil
In diesem Beispiel werden einige der oben genannten Empfehlungen für ein TabView-Element implementiert. Insbesondere implementiert dieses Beispiel STRG + T, STRG + W, STRG + 1-8und STRG + 9.
<TabView>
<!-- ... some tabs ... -->
<TabView.KeyboardAccelerators>
<KeyboardAccelerator Key="T" Modifiers="Control"
Invoked="NewTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="W" Modifiers="Control"
Invoked="CloseSelectedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number1" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number2" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number3" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number4" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number5" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number6" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number7" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number8" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number9" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
</TabView.KeyboardAccelerators>
</TabView>
private void NewTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
// Create new tab.
TabView senderTabView = (TabView)args.Element;
if (senderTabView != null)
{
// (Click handler defined in previous example.)
TabView_AddTabButtonClick(senderTabView, new EventArgs());
}
args.Handled = true;
}
private void CloseSelectedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
TabView tabView = (TabView)args.Element;
TabViewItem tab = (TabViewItem)tabView.SelectedItem;
// Only remove the selected tab if it can be closed.
if (tabView is not null &&
tab.IsClosable == true)
{
tabView.TabItems.Remove(tab);
}
args.Handled = true;
}
private void NavigateToNumberedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
TabView tabView = (TabView)args.Element;
int tabToSelect = 0;
switch (sender.Key)
{
case Windows.System.VirtualKey.Number1:
tabToSelect = 0;
break;
case Windows.System.VirtualKey.Number2:
tabToSelect = 1;
break;
case Windows.System.VirtualKey.Number3:
tabToSelect = 2;
break;
case Windows.System.VirtualKey.Number4:
tabToSelect = 3;
break;
case Windows.System.VirtualKey.Number5:
tabToSelect = 4;
break;
case Windows.System.VirtualKey.Number6:
tabToSelect = 5;
break;
case Windows.System.VirtualKey.Number7:
tabToSelect = 6;
break;
case Windows.System.VirtualKey.Number8:
tabToSelect = 7;
break;
case Windows.System.VirtualKey.Number9:
// Select the last tab
tabToSelect = tabView.TabItems.Count - 1;
break;
}
// Only select the tab if it is in the list.
if (tabToSelect < tabView.TabItems.Count)
{
tabView.SelectedIndex = tabToSelect;
}
}
UWP und WinUI 2
Wichtig
Die Informationen und Beispiele in diesem Artikel sind für Apps optimiert, die das Windows App SDK und WinUI 3verwenden, gelten jedoch im Allgemeinen für UWP-Apps, die WinUI 2verwenden. In der UWP-API-Referenz finden Sie plattformspezifische Informationen und Beispiele.
Dieser Abschnitt enthält Informationen, die Sie zum Verwenden des Steuerelements in einer UWP- oder WinUI 2-App benötigen.
Das TabView-Steuerelement für UWP-Apps ist als Teil von WinUI 2 enthalten. Weitere Informationen, einschließlich Installationsanweisungen, finden Sie unter WinUI 2. APIs für dieses Steuerelement sind im Microsoft.UI.Xaml.Controls Namespace vorhanden.
Die APIs zum Herausziehen von Registerkarten sind in der WinUI 2-Version von TabView nicht enthalten.
- WinUI 2 Apis:TabView Klasse, TabViewItem Klasse
- Öffnen Sie die WinUI 2 Gallery App und sehen Sie sich TabView in Aktion an. Die WinUI 2 Gallery App enthält interaktive Beispiele für die meisten WinUI 2-Steuerelemente, -Features und -Funktionen. Laden Sie die App aus dem Microsoft Store herunter oder laden Sie den Quellcode auf GitHubherunter.
Es wird empfohlen, die neueste WinUI 2-Version zu verwenden, um die aktuellsten Formatvorlagen, Vorlagen und Features für alle Steuerelemente abzurufen. WinUI 2.2 oder höher enthält eine neue Vorlage für dieses Steuerelement, die abgerundete Ecken verwendet. Weitere Informationen finden Sie unter Eckradius.
Um den Code in diesem Artikel mit WinUI 2 zu verwenden, verwenden Sie einen Alias in XAML (wir verwenden muxc
), um die Windows-UI-Bibliotheks-APIs darzustellen, die in Ihrem Projekt enthalten sind. Weitere Informationen finden Sie unter "Erste Schritte mit WinUI 2".
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:TabView />
Verwandte Artikel
Windows developer