Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Panel Elemente sind Komponenten, die das Rendern von Elementen steuern , deren Größe und Abmessungen, ihre Position und die Anordnung des untergeordneten Inhalts. Die Windows Presentation Foundation (WPF) bietet eine Reihe vordefinierter Panel Elemente sowie die Möglichkeit, benutzerdefinierte Panel Elemente zu erstellen.
Dieses Thema enthält folgende Abschnitte:
Die Panel-Klasse
Panel ist die Basisklasse für alle Elemente, die Layoutunterstützung in Windows Presentation Foundation (WPF) bereitstellen. Abgeleitete Panel Elemente werden verwendet, um Elemente in Extensible Application Markup Language (XAML) und Code zu positionieren und anzuordnen.
Der WPF enthält eine umfassende Suite abgeleiteter Panelimplementierungen, die viele komplexe Layouts ermöglichen. Diese abgeleiteten Klassen machen Eigenschaften und Methoden verfügbar, die die meisten Standardbenutzeroberflächenszenarien ermöglichen. Entwickler, die kein Kind-Anordnungsverhalten finden können, das ihren Anforderungen entspricht, können neue Layouts erstellen, indem sie die Methoden ArrangeOverride und MeasureOverride überschreiben. Weitere Informationen zu benutzerdefinierten Layoutverhalten finden Sie unter "Benutzerdefinierte Panelelemente".
Gemeinsame Mitglieder des Panels
Alle Panel-Elemente unterstützen die Basisgrößen- und Positionierungseigenschaften, die durch FrameworkElement definiert sind, einschließlich Height, Width, HorizontalAlignment, VerticalAlignment, Margin und LayoutTransform. Weitere Informationen zu positionierungseigenschaften, die durch FrameworkElementdefiniert werden, finden Sie unter "Alignment", "Margins" und "Padding Overview".
Panel macht zusätzliche Eigenschaften verfügbar, die für das Verständnis und die Verwendung des Layouts von entscheidender Bedeutung sind. Die Background-Eigenschaft wird verwendet, um den Bereich zwischen den Begrenzungen eines abgeleiteten Panelelements mit einem Brush zu füllen. Children stellt die untergeordnete Auflistung von Elementen dar, aus denen Panel besteht. InternalChildren stellt den Inhalt der Children Auflistung sowie die Elemente dar, die durch die Datenbindung generiert werden. Beide bestehen aus einer UIElementCollection Gruppe von untergeordneten Elementen, die im übergeordneten Element Panel gehostet werden.
Panel macht auch eine Panel.ZIndex angefügte Eigenschaft verfügbar, die verwendet werden kann, um eine Schichtreihenfolge in einem abgeleiteten Panel zu erzielen. Elemente der Auflistung eines Panels Children mit einem höheren Panel.ZIndex Wert werden vor denen mit einem niedrigeren Panel.ZIndex Wert angezeigt. Dies ist besonders nützlich für Panels wie Canvas und Grid, die es ermöglichen, dass untergeordnete Elemente denselben Koordinatenbereich teilen.
Panel definiert auch die OnRender Methode, die verwendet werden kann, um das Standarddarstellungsverhalten eines Panel.
Angefügte Eigenschaften
Abgeleitete Panelelemente nutzen umfangreiche angefügte Eigenschaften. Eine angefügte Eigenschaft ist eine spezielle Form von Abhängigkeitseigenschaft, die nicht über die herkömmliche Common Language Runtime (CLR)-Eigenschaft "wrapper" verfügt. Angefügte Eigenschaften weisen eine spezielle Syntax in Extensible Application Markup Language (XAML) auf, die in mehreren beispielen zu sehen ist.
Ein Zweck einer angefügten Eigenschaft besteht darin, untergeordneten Elementen das Speichern eindeutiger Werte einer Eigenschaft zu ermöglichen, die tatsächlich durch ein übergeordnetes Element definiert wird. Eine Möglichkeit dieser Funktionalität besteht darin, dass untergeordnete Elemente das Elternelement darüber informieren, wie sie in einer Benutzeroberfläche dargestellt werden möchten, was für das Layout von Anwendungen äußerst nützlich ist. Weitere Informationen finden Sie unter "Übersicht über angefügte Eigenschaften".
Abgeleitete Panelelemente
Viele Objekte stammen von Panel, aber nicht alle objekte sind für die Verwendung als Stammlayoutanbieter vorgesehen. Es gibt sechs definierte Panelklassen (Canvas, , DockPanel, GridStackPanel, VirtualizingStackPanelund WrapPanel), die speziell für die Erstellung der Anwendungs-UI entwickelt wurden.
Jedes Panelelement kapselt seine eigene spezielle Funktionalität, wie in der folgenden Tabelle dargestellt.
Elementname | UI-Bereich? | BESCHREIBUNG |
---|---|---|
Canvas | Ja | Definiert einen Bereich, in dem Sie mithilfe von Koordinaten, die relativ zum Canvas-Bereich sind, explizit untergeordnete Elemente positionieren können. |
DockPanel | Ja | Definiert einen Bereich, in dem Sie untergeordnete Elemente entweder horizontal oder vertikal relativ zueinander anordnen können. |
Grid | Ja | Definiert einen flexiblen Rasterbereich, der aus Spalten und Zeilen besteht. Untergeordnete Elemente eines Objekts Grid können präzise mithilfe der Margin Eigenschaft positioniert werden. |
StackPanel | Ja | Ordnet untergeordnete Elemente in einer einzelnen Zeile an, die horizontal oder vertikal ausgerichtet werden kann. |
TabPanel | Nein | Verwaltet das Layout von Tab-Schaltflächen in einem TabControl. |
ToolBarOverflowPanel | Nein | Ordnet Inhalte innerhalb eines ToolBar-Steuerelements an. |
UniformGrid | Nein | UniformGrid wird verwendet, um Kinder in einem Raster mit gleich großen Zellen anzuordnen. |
VirtualizingPanel | Nein | Stellt eine Basisklasse für Panels bereit, die ihre untergeordnete Sammlung "virtualisieren" können. |
VirtualizingStackPanel | Ja | Ordnet Inhalte in einer einzelnen Linie horizontal oder vertikal an und virtualisiert sie. |
WrapPanel | Ja | WrapPanel Positioniert untergeordnete Elemente in sequenzieller Position von links nach rechts, wobei der Inhalt an der nächsten Zeile am Rand des enthaltenden Felds unterbrochen wird. Nachfolgende Sortierung erfolgt sequenziell von oben nach unten oder von rechts nach links, je nach Wert der Orientation Eigenschaft. |
Bedienoberflächen-Panels
In WPF sind sechs Panelklassen verfügbar, die für die Unterstützung von UI-Szenarien optimiert sind: Canvas, , , DockPanel, Grid, StackPanel, und VirtualizingStackPanelWrapPanel. Diese Panelelemente sind für die meisten Anwendungen einfach zu verwenden, vielseitig und erweiterbar.
Jedes abgeleitete Panel Element behandelt Größenbeschränkungen unterschiedlich. Zu verstehen, wie Panel Einschränkungen in horizontaler oder vertikaler Richtung behandelt, kann das Layout vorhersehbarer machen.
Panelname | x-Dimension | y-Dimension |
---|---|---|
Canvas | Auf Inhalte beschränkt | Auf Inhalte beschränkt |
DockPanel | Eingeschränkt | Eingeschränkt |
StackPanel (Vertikale Ausrichtung) | Eingeschränkt | Auf Inhalte beschränkt |
StackPanel (Horizontale Ausrichtung) | Auf Inhalte beschränkt | Eingeschränkt |
Grid | Eingeschränkt | Eingeschränkt, außer in Fällen, in denen Auto Zeilen und Spalten angewendet werden |
WrapPanel | Auf Inhalte beschränkt | Auf Inhalte beschränkt |
Ausführlichere Beschreibungen und Verwendungsbeispiele für jedes dieser Elemente finden Sie unten.
Leinwand
Das Canvas Element ermöglicht die Positionierung von Inhalten gemäß absoluten x- und y-Koordinaten . Elemente können an einer eindeutigen Position gezeichnet werden; oder wenn Elemente die gleichen Koordinaten belegen, bestimmt die Reihenfolge, in der sie im Markup angezeigt werden, die Reihenfolge, in der die Elemente gezeichnet werden.
Canvas bietet die flexibelste Layoutunterstützung für alle Panel. Die Eigenschaften "Height" und "Width" werden verwendet, um den Bereich des Zeichenbereichs zu definieren, und Elementen innerhalb davon werden absolute Koordinaten relativ zum Bereich des übergeordneten CanvasElements zugewiesen. Vier angefügte Eigenschaften, Canvas.Left, Canvas.TopCanvas.Right und Canvas.Bottom, ermöglichen eine feine Kontrolle über die Objektplatzierung innerhalb eines CanvasObjekts, sodass der Entwickler Elemente präzise auf dem Bildschirm positionieren und anordnen kann.
ClipToBounds innerhalb einer Canvas
Canvas kann untergeordnete Elemente an einer beliebigen Position auf dem Bildschirm positionieren, auch bei Koordinaten, die sich außerhalb seiner eigenen definierten Height und Width befinden.
Canvas wird darüber hinaus nicht von der Größe seiner Kinder beeinflusst. Daher ist es möglich, dass ein untergeordnetes Element andere Elemente außerhalb des umgebenden Rechtecks des übergeordneten Canvas überlagert. Das Standardverhalten von a Canvas ist das Zulassen, dass untergeordnete Elemente außerhalb der Grenzen des übergeordneten Elements Canvasgezeichnet werden. Wenn dieses Verhalten nicht erwünscht ist, kann die Eigenschaft ClipToBounds auf true
gesetzt werden. Dies führt dazu, dass Canvas auf seine eigene Größe abgeschnitten wird.
Canvas ist das einzige Layoutelement, mit dem untergeordnete Elemente außerhalb seiner Grenzen gezeichnet werden können.
Dieses Verhalten wird im Vergleichsbeispiel für Breiteneigenschaften grafisch veranschaulicht.
Definieren und Verwenden einer Zeichenfläche
Eine Canvas kann einfach mithilfe von Extensible Application Markup Language (XAML) oder Code instanziiert werden. Das folgende Beispiel zeigt, wie man Inhalte mit Canvas absolut positioniert. Dieser Code erzeugt drei Quadrate mit 100 Pixeln. Das erste Quadrat ist rot, und seine obere linke Position (x, y) wird als (0, 0) angegeben. Das zweite Quadrat ist grün, und seine obere linke Position ist (100, 100), direkt unter und rechts vom ersten Quadrat. Das dritte Quadrat ist blau, und seine obere linke Ecke ist (50, 50), wodurch der untere rechte Quadrant des ersten Quadrats und der obere linke Quadrant des zweiten Quadrats umfasst werden. Da das dritte Quadrat zuletzt angeordnet ist, scheint es sich auf den anderen beiden Quadraten zu befinden, d. h., die überlappenden Teile nehmen die Farbe der dritten Box an.
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "Canvas Sample";
// Create the Canvas
myParentCanvas = new Canvas();
myParentCanvas.Width = 400;
myParentCanvas.Height = 400;
// Define child Canvas elements
myCanvas1 = new Canvas();
myCanvas1.Background = Brushes.Red;
myCanvas1.Height = 100;
myCanvas1.Width = 100;
Canvas.SetTop(myCanvas1, 0);
Canvas.SetLeft(myCanvas1, 0);
myCanvas2 = new Canvas();
myCanvas2.Background = Brushes.Green;
myCanvas2.Height = 100;
myCanvas2.Width = 100;
Canvas.SetTop(myCanvas2, 100);
Canvas.SetLeft(myCanvas2, 100);
myCanvas3 = new Canvas();
myCanvas3.Background = Brushes.Blue;
myCanvas3.Height = 100;
myCanvas3.Width = 100;
Canvas.SetTop(myCanvas3, 50);
Canvas.SetLeft(myCanvas3, 50);
// Add child elements to the Canvas' Children collection
myParentCanvas.Children.Add(myCanvas1);
myParentCanvas.Children.Add(myCanvas2);
myParentCanvas.Children.Add(myCanvas3);
// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myParentCanvas;
mainWindow.Show ();
WindowTitle = "Canvas Sample"
'Create a Canvas as the root Panel
Dim myParentCanvas As New Canvas()
myParentCanvas.Width = 400
myParentCanvas.Height = 400
' Define child Canvas elements
Dim myCanvas1 As New Canvas()
myCanvas1.Background = Brushes.Red
myCanvas1.Height = 100
myCanvas1.Width = 100
Canvas.SetTop(myCanvas1, 0)
Canvas.SetLeft(myCanvas1, 0)
Dim myCanvas2 As New Canvas()
myCanvas2.Background = Brushes.Green
myCanvas2.Height = 100
myCanvas2.Width = 100
Canvas.SetTop(myCanvas2, 100)
Canvas.SetLeft(myCanvas2, 100)
Dim myCanvas3 As New Canvas()
myCanvas3.Background = Brushes.Blue
myCanvas3.Height = 100
myCanvas3.Width = 100
Canvas.SetTop(myCanvas3, 50)
Canvas.SetLeft(myCanvas3, 50)
' Add child elements to the Canvas' Children collection
myParentCanvas.Children.Add(myCanvas1)
myParentCanvas.Children.Add(myCanvas2)
myParentCanvas.Children.Add(myCanvas3)
' Add the parent Canvas as the Content of the Window Object
Me.Content = myParentCanvas
<Page WindowTitle="Canvas Sample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Canvas Height="400" Width="400">
<Canvas Height="100" Width="100" Top="0" Left="0" Background="Red"/>
<Canvas Height="100" Width="100" Top="100" Left="100" Background="Green"/>
<Canvas Height="100" Width="100" Top="50" Left="50" Background="Blue"/>
</Canvas>
</Page>
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
DockPanel
Das DockPanel-Element verwendet die angekoppelte DockPanel.Dock-Eigenschaft, die festgelegt ist in untergeordneten Inhaltselementen, um Inhalte an den Rändern eines Containers zu positionieren. Wenn DockPanel.Dock auf Top oder Bottom gesetzt ist, werden untergeordnete Elemente übereinander oder untereinander positioniert. Wenn DockPanel.Dock auf Left oder Right eingestellt ist, positioniert es untergeordnete Elemente links oder rechts. Die LastChildFill Eigenschaft bestimmt die Position des endgültigen Elements, das als untergeordnetes Element eines Elements DockPanelhinzugefügt wird.
Sie können DockPanel verwenden, um eine Gruppe verwandter Steuerelemente, wie etwa eine Gruppe von Schaltflächen, zu positionieren. Alternativ können Sie sie verwenden, um eine "verschiebte" Benutzeroberfläche zu erstellen, ähnlich wie in Microsoft Outlook.
Größe an Inhalt anpassen
Wenn die Eigenschaften Height und Width nicht angegeben sind, passt DockPanel seine Größe an den Inhalt an. Die Größe kann vergrößert oder verkleinert werden, um sich an die Größe der untergeordneten Elemente anzupassen. Wenn diese Eigenschaften angegeben werden und es keinen Platz für das nächste angegebene untergeordnete Element mehr gibt, zeigt DockPanel dieses untergeordnete Element sowie nachfolgende untergeordnete Elemente nicht an und misst diese auch nicht.
LastChildFill
Standardmäßig wird das letzte untergeordnete Element eines DockPanel Elements den verbleibenden, nicht zugewiesenen Bereich "ausfüllen". Wenn dieses Verhalten nicht gewünscht ist, legen Sie die LastChildFill Eigenschaft auf false
.
Definieren und Verwenden eines DockPanel
Das folgende Beispiel demonstriert, wie man mithilfe eines DockPanel Speicherplatz partitionieren kann. Fünf Border Elemente werden als untergeordnete Elemente eines übergeordneten Elements DockPanelhinzugefügt. Jede verwendet eine andere Positionierungseigenschaft eines DockPanel-Elements, um Raum zu unterteilen. Das letzte Element "füllt" den verbleibenden, nicht zugewiesenen Raum.
// Create the application's main window
mainWindow = gcnew Window();
mainWindow->Title = "DockPanel Sample";
// Create the DockPanel
DockPanel^ myDockPanel = gcnew DockPanel();
myDockPanel->LastChildFill = true;
// Define the child content
Border^ myBorder1 = gcnew Border();
myBorder1->Height = 25;
myBorder1->Background = Brushes::SkyBlue;
myBorder1->BorderBrush = Brushes::Black;
myBorder1->BorderThickness = Thickness(1);
DockPanel::SetDock(myBorder1, Dock::Top);
TextBlock^ myTextBlock1 = gcnew TextBlock();
myTextBlock1->Foreground = Brushes::Black;
myTextBlock1->Text = "Dock = Top";
myBorder1->Child = myTextBlock1;
Border^ myBorder2 = gcnew Border();
myBorder2->Height = 25;
myBorder2->Background = Brushes::SkyBlue;
myBorder2->BorderBrush = Brushes::Black;
myBorder2->BorderThickness = Thickness(1);
DockPanel::SetDock(myBorder2, Dock::Top);
TextBlock^ myTextBlock2 = gcnew TextBlock();
myTextBlock2->Foreground = Brushes::Black;
myTextBlock2->Text = "Dock = Top";
myBorder2->Child = myTextBlock2;
Border^ myBorder3 = gcnew Border();
myBorder3->Height = 25;
myBorder3->Background = Brushes::LemonChiffon;
myBorder3->BorderBrush = Brushes::Black;
myBorder3->BorderThickness = Thickness(1);
DockPanel::SetDock(myBorder3, Dock::Bottom);
TextBlock^ myTextBlock3 = gcnew TextBlock();
myTextBlock3->Foreground = Brushes::Black;
myTextBlock3->Text = "Dock = Bottom";
myBorder3->Child = myTextBlock3;
Border^ myBorder4 = gcnew Border();
myBorder4->Width = 200;
myBorder4->Background = Brushes::PaleGreen;
myBorder4->BorderBrush = Brushes::Black;
myBorder4->BorderThickness = Thickness(1);
DockPanel::SetDock(myBorder4, Dock::Left);
TextBlock^ myTextBlock4 = gcnew TextBlock();
myTextBlock4->Foreground = Brushes::Black;
myTextBlock4->Text = "Dock = Left";
myBorder4->Child = myTextBlock4;
Border^ myBorder5 = gcnew Border();
myBorder5->Background = Brushes::White;
myBorder5->BorderBrush = Brushes::Black;
myBorder5->BorderThickness = Thickness(1);
TextBlock^ myTextBlock5 = gcnew TextBlock();
myTextBlock5->Foreground = Brushes::Black;
myTextBlock5->Text = "This content will Fill the remaining space";
myBorder5->Child = myTextBlock5;
// Add child elements to the DockPanel Children collection
myDockPanel->Children->Add(myBorder1);
myDockPanel->Children->Add(myBorder2);
myDockPanel->Children->Add(myBorder3);
myDockPanel->Children->Add(myBorder4);
myDockPanel->Children->Add(myBorder5);
// Add the parent Canvas as the Content of the Window Object
mainWindow->Content = myDockPanel;
mainWindow->Show();
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "DockPanel Sample";
// Create the DockPanel
DockPanel myDockPanel = new DockPanel();
myDockPanel.LastChildFill = true;
// Define the child content
Border myBorder1 = new Border();
myBorder1.Height = 25;
myBorder1.Background = Brushes.SkyBlue;
myBorder1.BorderBrush = Brushes.Black;
myBorder1.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder1, Dock.Top);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.Foreground = Brushes.Black;
myTextBlock1.Text = "Dock = Top";
myBorder1.Child = myTextBlock1;
Border myBorder2 = new Border();
myBorder2.Height = 25;
myBorder2.Background = Brushes.SkyBlue;
myBorder2.BorderBrush = Brushes.Black;
myBorder2.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder2, Dock.Top);
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Foreground = Brushes.Black;
myTextBlock2.Text = "Dock = Top";
myBorder2.Child = myTextBlock2;
Border myBorder3 = new Border();
myBorder3.Height = 25;
myBorder3.Background = Brushes.LemonChiffon;
myBorder3.BorderBrush = Brushes.Black;
myBorder3.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder3, Dock.Bottom);
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Foreground = Brushes.Black;
myTextBlock3.Text = "Dock = Bottom";
myBorder3.Child = myTextBlock3;
Border myBorder4 = new Border();
myBorder4.Width = 200;
myBorder4.Background = Brushes.PaleGreen;
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Left);
TextBlock myTextBlock4 = new TextBlock();
myTextBlock4.Foreground = Brushes.Black;
myTextBlock4.Text = "Dock = Left";
myBorder4.Child = myTextBlock4;
Border myBorder5 = new Border();
myBorder5.Background = Brushes.White;
myBorder5.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
TextBlock myTextBlock5 = new TextBlock();
myTextBlock5.Foreground = Brushes.Black;
myTextBlock5.Text = "This content will Fill the remaining space";
myBorder5.Child = myTextBlock5;
// Add child elements to the DockPanel Children collection
myDockPanel.Children.Add(myBorder1);
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);
// Add the parent Canvas as the Content of the Window Object
mainWindow.Content = myDockPanel;
mainWindow.Show ();
WindowTitle = "DockPanel Sample"
'Create a DockPanel as the root Panel
Dim myDockPanel As New DockPanel()
myDockPanel.LastChildFill = True
' Define the child content
Dim myBorder1 As New Border()
myBorder1.Height = 25
myBorder1.Background = Brushes.SkyBlue
myBorder1.BorderBrush = Brushes.Black
myBorder1.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder1, Dock.Top)
Dim myTextBlock1 As New TextBlock()
myTextBlock1.Foreground = Brushes.Black
myTextBlock1.Text = "Dock = Top"
myBorder1.Child = myTextBlock1
Dim myBorder2 As New Border()
myBorder2.Height = 25
myBorder2.Background = Brushes.SkyBlue
myBorder2.BorderBrush = Brushes.Black
myBorder2.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder2, Dock.Top)
Dim myTextBlock2 As New TextBlock()
myTextBlock2.Foreground = Brushes.Black
myTextBlock2.Text = "Dock = Top"
myBorder2.Child = myTextBlock2
Dim myBorder3 As New Border()
myBorder3.Height = 25
myBorder3.Background = Brushes.LemonChiffon
myBorder3.BorderBrush = Brushes.Black
myBorder3.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder3, Dock.Bottom)
Dim myTextBlock3 As New TextBlock()
myTextBlock3.Foreground = Brushes.Black
myTextBlock3.Text = "Dock = Bottom"
myBorder3.Child = myTextBlock3
Dim myBorder4 As New Border()
myBorder4.Width = 200
myBorder4.Background = Brushes.PaleGreen
myBorder4.BorderBrush = Brushes.Black
myBorder4.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder4, Dock.Left)
Dim myTextBlock4 As New TextBlock()
myTextBlock4.Foreground = Brushes.Black
myTextBlock4.Text = "Dock = Left"
myBorder4.Child = myTextBlock4
Dim myBorder5 As New Border()
myBorder5.Background = Brushes.White
myBorder5.BorderBrush = Brushes.Black
myBorder5.BorderThickness = New Thickness(1)
Dim myTextBlock5 As New TextBlock()
myTextBlock5.Foreground = Brushes.Black
myTextBlock5.Text = "This content will Fill the remaining space"
myBorder5.Child = myTextBlock5
' Add child elements to the DockPanel Children collection
myDockPanel.Children.Add(myBorder1)
myDockPanel.Children.Add(myBorder2)
myDockPanel.Children.Add(myBorder3)
myDockPanel.Children.Add(myBorder4)
myDockPanel.Children.Add(myBorder5)
Me.Content = myDockPanel
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="DockPanel Sample">
<DockPanel LastChildFill="True">
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="SkyBlue" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
<TextBlock Foreground="Black">Dock = "Top"</TextBlock>
</Border>
<Border Height="25" Background="LemonChiffon" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
<TextBlock Foreground="Black">Dock = "Bottom"</TextBlock>
</Border>
<Border Width="200" Background="PaleGreen" BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
<TextBlock Foreground="Black">Dock = "Left"</TextBlock>
</Border>
<Border Background="White" BorderBrush="Black" BorderThickness="1">
<TextBlock Foreground="Black">This content will "Fill" the remaining space</TextBlock>
</Border>
</DockPanel>
</Page>
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
Raster
Das Grid Element führt die Funktionalität eines absoluten Positionierungs- und Tabellendatensteuerelements zusammen. Mithilfe eines Grid Steuerelements können Sie Elemente auf einfache Weise positionieren und formatieren. Grid ermöglicht es Ihnen, flexible Zeilen- und Spaltengruppierungen zu definieren, und bietet sogar einen Mechanismus zum Freigeben von Größeninformationen zwischen mehreren Grid Elementen.
Unterschiede zwischen Rastern und Tabellen
Table und Grid teilen einige gemeinsame Funktionen, aber jedes eignet sich am besten für verschiedene Szenarien. A Table ist für die Verwendung innerhalb von Flussinhalten vorgesehen (siehe Flussdokumentübersicht für weitere Informationen zu Flussinhalten). Raster werden am besten innerhalb von Formularen verwendet (im Grunde überall außerhalb des Flussinhalts). In einem FlowDocument unterstützt Table Flussinhaltsverhalten wie Paginierung, Spaltenumbruch und Inhaltsauswahl, während ein Grid dies nicht unterstützt. Eine Grid dagegen wird außerhalb einer FlowDocument aus einer Reihe von Gründen am besten verwendet, einschließlich Grid das Hinzufügen von Elementen, die auf einem Zeilen- und Spaltenindex basieren, während Table dies nicht tut. Das Grid-Element ermöglicht das Layern von untergeordneten Inhalten, sodass mehrere Elemente in einer einzigen "Zelle" vorhanden sind. Das Table-Element unterstützt die Layerung nicht. Untergeordnete Elemente eines Elements Grid können absolut relativ zum Bereich ihrer "Zellgrenzen" positioniert werden. Table unterstützt dieses Feature nicht. Schließlich ist ein Grid leichter als ein Table.
Größenanpassung von Spalten und Zeilen
Spalten und Zeilen, die innerhalb einer Grid Definition definiert sind, können die Star Größenanpassung nutzen, um den verbleibenden Platz proportional zu verteilen. Wenn Star als Höhe oder Breite einer Zeile oder Spalte ausgewählt wird, erhält die betreffende Spalte oder Zeile einen gewichteten Anteil des verbleibenden verfügbaren Platzes. Dies ist im Gegensatz zu Auto, die den Platz gleichmäßig basierend auf der Größe des Inhalts innerhalb einer Spalte oder Zeile verteilt. Dieser Wert wird als *
oder 2*
bei Verwendung von Extensible Application Markup Language (XAML) ausgedrückt. Im ersten Fall würde die Zeile oder Spalte einmal den verfügbaren Platz erhalten, im zweiten Fall zweimal usw. Durch die Kombination dieser Technik zum proportionalen Verteilen des Raums mit einem HorizontalAlignment- und VerticalAlignment-Wert von Stretch
ist es möglich, den Layoutraum prozentual auf den Bildschirmbereich aufzuteilen.
Grid ist der einzige Layoutbereich, der Platz auf diese Weise verteilen kann.
Definieren und Verwenden eines Rasters
Das folgende Beispiel zeigt, wie Sie eine Benutzeroberfläche erstellen, die der im Dialogfeld "Ausführen" des Windows-Startmenüs ähnlich ist.
// Create the Grid.
grid1 = new Grid ();
grid1.Background = Brushes.Gainsboro;
grid1.HorizontalAlignment = HorizontalAlignment.Left;
grid1.VerticalAlignment = VerticalAlignment.Top;
grid1.ShowGridLines = true;
grid1.Width = 425;
grid1.Height = 165;
// Define the Columns.
colDef1 = new ColumnDefinition();
colDef1.Width = new GridLength(1, GridUnitType.Auto);
colDef2 = new ColumnDefinition();
colDef2.Width = new GridLength(1, GridUnitType.Star);
colDef3 = new ColumnDefinition();
colDef3.Width = new GridLength(1, GridUnitType.Star);
colDef4 = new ColumnDefinition();
colDef4.Width = new GridLength(1, GridUnitType.Star);
colDef5 = new ColumnDefinition();
colDef5.Width = new GridLength(1, GridUnitType.Star);
grid1.ColumnDefinitions.Add(colDef1);
grid1.ColumnDefinitions.Add(colDef2);
grid1.ColumnDefinitions.Add(colDef3);
grid1.ColumnDefinitions.Add(colDef4);
grid1.ColumnDefinitions.Add(colDef5);
// Define the Rows.
rowDef1 = new RowDefinition();
rowDef1.Height = new GridLength(1, GridUnitType.Auto);
rowDef2 = new RowDefinition();
rowDef2.Height = new GridLength(1, GridUnitType.Auto);
rowDef3 = new RowDefinition();
rowDef3.Height = new GridLength(1, GridUnitType.Star);
rowDef4 = new RowDefinition();
rowDef4.Height = new GridLength(1, GridUnitType.Auto);
grid1.RowDefinitions.Add(rowDef1);
grid1.RowDefinitions.Add(rowDef2);
grid1.RowDefinitions.Add(rowDef3);
grid1.RowDefinitions.Add(rowDef4);
// Add the Image.
img1 = new Image();
img1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("runicon.png", UriKind.Relative));
Grid.SetRow(img1, 0);
Grid.SetColumn(img1, 0);
// Add the main application dialog.
txt1 = new TextBlock();
txt1.Text = "Type the name of a program, folder, document, or Internet resource, and Windows will open it for you.";
txt1.TextWrapping = TextWrapping.Wrap;
Grid.SetColumnSpan(txt1, 4);
Grid.SetRow(txt1, 0);
Grid.SetColumn(txt1, 1);
// Add the second text cell to the Grid.
txt2 = new TextBlock();
txt2.Text = "Open:";
Grid.SetRow(txt2, 1);
Grid.SetColumn(txt2, 0);
// Add the TextBox control.
tb1 = new TextBox();
Grid.SetRow(tb1, 1);
Grid.SetColumn(tb1, 1);
Grid.SetColumnSpan(tb1, 5);
// Add the buttons.
button1 = new Button();
button2 = new Button();
button3 = new Button();
button1.Content = "OK";
button2.Content = "Cancel";
button3.Content = "Browse ...";
Grid.SetRow(button1, 3);
Grid.SetColumn(button1, 2);
button1.Margin = new Thickness(10, 0, 10, 15);
button2.Margin = new Thickness(10, 0, 10, 15);
button3.Margin = new Thickness(10, 0, 10, 15);
Grid.SetRow(button2, 3);
Grid.SetColumn(button2, 3);
Grid.SetRow(button3, 3);
Grid.SetColumn(button3, 4);
grid1.Children.Add(img1);
grid1.Children.Add(txt1);
grid1.Children.Add(txt2);
grid1.Children.Add(tb1);
grid1.Children.Add(button1);
grid1.Children.Add(button2);
grid1.Children.Add(button3);
mainWindow.Content = grid1;
'Create a Grid as the root Panel element.
Dim myGrid As New Grid()
myGrid.Height = 165
myGrid.Width = 425
myGrid.Background = Brushes.Gainsboro
myGrid.ShowGridLines = True
myGrid.HorizontalAlignment = Windows.HorizontalAlignment.Left
myGrid.VerticalAlignment = Windows.VerticalAlignment.Top
' Define and Add the Rows and Columns.
Dim colDef1 As New ColumnDefinition
colDef1.Width = New GridLength(1, GridUnitType.Auto)
Dim colDef2 As New ColumnDefinition
colDef2.Width = New GridLength(1, GridUnitType.Star)
Dim colDef3 As New ColumnDefinition
colDef3.Width = New GridLength(1, GridUnitType.Star)
Dim colDef4 As New ColumnDefinition
colDef4.Width = New GridLength(1, GridUnitType.Star)
Dim colDef5 As New ColumnDefinition
colDef5.Width = New GridLength(1, GridUnitType.Star)
myGrid.ColumnDefinitions.Add(colDef1)
myGrid.ColumnDefinitions.Add(colDef2)
myGrid.ColumnDefinitions.Add(colDef3)
myGrid.ColumnDefinitions.Add(colDef4)
myGrid.ColumnDefinitions.Add(colDef5)
Dim rowDef1 As New RowDefinition
rowDef1.Height = New GridLength(1, GridUnitType.Auto)
Dim rowDef2 As New RowDefinition
rowDef2.Height = New GridLength(1, GridUnitType.Auto)
Dim rowDef3 As New Controls.RowDefinition
rowDef3.Height = New GridLength(1, GridUnitType.Star)
Dim rowDef4 As New RowDefinition
rowDef4.Height = New GridLength(1, GridUnitType.Auto)
myGrid.RowDefinitions.Add(rowDef1)
myGrid.RowDefinitions.Add(rowDef2)
myGrid.RowDefinitions.Add(rowDef3)
myGrid.RowDefinitions.Add(rowDef4)
' Add the Image.
Dim img1 As New Image
img1.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("runicon.png", UriKind.Relative))
Grid.SetRow(img1, 0)
Grid.SetColumn(img1, 0)
myGrid.Children.Add(img1)
' Add the main application dialog.
Dim txt1 As New TextBlock
txt1.Text = "Type the name of a program, document, or Internet resource, and Windows will open it for you."
txt1.TextWrapping = TextWrapping.Wrap
Grid.SetColumnSpan(txt1, 4)
Grid.SetRow(txt1, 0)
Grid.SetColumn(txt1, 1)
myGrid.Children.Add(txt1)
' Add the second TextBlock Cell to the Grid.
Dim txt2 As New TextBlock
txt2.Text = "Open:"
Grid.SetRow(txt2, 1)
Grid.SetColumn(txt2, 0)
myGrid.Children.Add(txt2)
' Add the TextBox control.
Dim tb1 As New TextBox
Grid.SetRow(tb1, 1)
Grid.SetColumn(tb1, 1)
Grid.SetColumnSpan(tb1, 5)
myGrid.Children.Add(tb1)
' Add the Button controls.
Dim button1 As New Button
Dim button2 As New Button
Dim button3 As New Button
button1.Content = "OK"
button1.Margin = New Thickness(10, 0, 10, 15)
button2.Content = "Cancel"
button2.Margin = New Thickness(10, 0, 10, 15)
button3.Content = "Browse ..."
button3.Margin = New Thickness(10, 0, 10, 15)
Grid.SetRow(button1, 3)
Grid.SetColumn(button1, 2)
Grid.SetRow(button2, 3)
Grid.SetColumn(button2, 3)
Grid.SetRow(button3, 3)
Grid.SetColumn(button3, 4)
myGrid.Children.Add(button1)
myGrid.Children.Add(button2)
myGrid.Children.Add(button3)
Me.Content = myGrid
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
StackPanel
Mit einer StackPanel Option können Sie Elemente in einer zugewiesenen Richtung "stapeln". Die Standardstapelrichtung ist vertikal. Die Orientation Eigenschaft kann zum Steuern des Inhaltsflusses verwendet werden.
StackPanel im Vergleich zu DockPanel
Obwohl DockPanel auch untergeordnete Elemente "stapeln" kann, erzeugen DockPanel und StackPanel keine analogen Ergebnisse in einigen Verwendungsszenarien. Die Reihenfolge der untergeordneten Elemente kann sich beispielsweise auf ihre Größe in einem DockPanel-Element auswirken, aber nicht in einem StackPanel-Element. Dies liegt daran, dass StackPanel im Sinne der Stapelrichtung PositiveInfinity misst, während DockPanel nur die verfügbare Größe misst.
Im folgenden Beispiel wird dieser Hauptunterschied veranschaulicht.
// Create the application's main window
mainWindow = gcnew Window();
mainWindow->Title = "StackPanel vs. DockPanel";
// Add root Grid
myGrid = gcnew Grid();
myGrid->Width = 175;
myGrid->Height = 150;
RowDefinition^ myRowDef1 = gcnew RowDefinition();
RowDefinition^ myRowDef2 = gcnew RowDefinition();
myGrid->RowDefinitions->Add(myRowDef1);
myGrid->RowDefinitions->Add(myRowDef2);
// Define the DockPanel
myDockPanel = gcnew DockPanel();
Grid::SetRow(myDockPanel, 0);
//Define an Image and Source
Image^ myImage = gcnew Image();
BitmapImage^ bi = gcnew BitmapImage();
bi->BeginInit();
bi->UriSource = gcnew System::Uri("smiley_stackpanel.png", UriKind::Relative);
bi->EndInit();
myImage->Source = bi;
Image^ myImage2 = gcnew Image();
BitmapImage^ bi2 = gcnew BitmapImage();
bi2->BeginInit();
bi2->UriSource = gcnew System::Uri("smiley_stackpanel.png", UriKind::Relative);
bi2->EndInit();
myImage2->Source = bi2;
Image^ myImage3 = gcnew Image();
BitmapImage^ bi3 = gcnew BitmapImage();
bi3->BeginInit();
bi3->UriSource = gcnew System::Uri("smiley_stackpanel.PNG", UriKind::Relative);
bi3->EndInit();
myImage3->Stretch = Stretch::Fill;
myImage3->Source = bi3;
// Add the images to the parent DockPanel
myDockPanel->Children->Add(myImage);
myDockPanel->Children->Add(myImage2);
myDockPanel->Children->Add(myImage3);
//Define a StackPanel
myStackPanel = gcnew StackPanel();
myStackPanel->Orientation = Orientation::Horizontal;
Grid::SetRow(myStackPanel, 1);
Image^ myImage4 = gcnew Image();
BitmapImage^ bi4 = gcnew BitmapImage();
bi4->BeginInit();
bi4->UriSource = gcnew System::Uri("smiley_stackpanel.png", UriKind::Relative);
bi4->EndInit();
myImage4->Source = bi4;
Image^ myImage5 = gcnew Image();
BitmapImage^ bi5 = gcnew BitmapImage();
bi5->BeginInit();
bi5->UriSource = gcnew System::Uri("smiley_stackpanel.png", UriKind::Relative);
bi5->EndInit();
myImage5->Source = bi5;
Image^ myImage6 = gcnew Image();
BitmapImage^ bi6 = gcnew BitmapImage();
bi6->BeginInit();
bi6->UriSource = gcnew System::Uri("smiley_stackpanel.PNG", UriKind::Relative);
bi6->EndInit();
myImage6->Stretch = Stretch::Fill;
myImage6->Source = bi6;
// Add the images to the parent StackPanel
myStackPanel->Children->Add(myImage4);
myStackPanel->Children->Add(myImage5);
myStackPanel->Children->Add(myImage6);
// Add the layout panels as children of the Grid
myGrid->Children->Add(myDockPanel);
myGrid->Children->Add(myStackPanel);
// Add the Grid as the Content of the Parent Window Object
mainWindow->Content = myGrid;
mainWindow->Show();
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "StackPanel vs. DockPanel";
// Add root Grid
myGrid = new Grid();
myGrid.Width = 175;
myGrid.Height = 150;
RowDefinition myRowDef1 = new RowDefinition();
RowDefinition myRowDef2 = new RowDefinition();
myGrid.RowDefinitions.Add(myRowDef1);
myGrid.RowDefinitions.Add(myRowDef2);
// Define the DockPanel
myDockPanel = new DockPanel();
Grid.SetRow(myDockPanel, 0);
//Define an Image and Source
Image myImage = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi.EndInit();
myImage.Source = bi;
Image myImage2 = new Image();
BitmapImage bi2 = new BitmapImage();
bi2.BeginInit();
bi2.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi2.EndInit();
myImage2.Source = bi2;
Image myImage3 = new Image();
BitmapImage bi3 = new BitmapImage();
bi3.BeginInit();
bi3.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative);
bi3.EndInit();
myImage3.Stretch = Stretch.Fill;
myImage3.Source = bi3;
// Add the images to the parent DockPanel
myDockPanel.Children.Add(myImage);
myDockPanel.Children.Add(myImage2);
myDockPanel.Children.Add(myImage3);
//Define a StackPanel
myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Horizontal;
Grid.SetRow(myStackPanel, 1);
Image myImage4 = new Image();
BitmapImage bi4 = new BitmapImage();
bi4.BeginInit();
bi4.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi4.EndInit();
myImage4.Source = bi4;
Image myImage5 = new Image();
BitmapImage bi5 = new BitmapImage();
bi5.BeginInit();
bi5.UriSource = new Uri("smiley_stackpanel.png", UriKind.Relative);
bi5.EndInit();
myImage5.Source = bi5;
Image myImage6 = new Image();
BitmapImage bi6 = new BitmapImage();
bi6.BeginInit();
bi6.UriSource = new Uri("smiley_stackpanel.PNG", UriKind.Relative);
bi6.EndInit();
myImage6.Stretch = Stretch.Fill;
myImage6.Source = bi6;
// Add the images to the parent StackPanel
myStackPanel.Children.Add(myImage4);
myStackPanel.Children.Add(myImage5);
myStackPanel.Children.Add(myImage6);
// Add the layout panels as children of the Grid
myGrid.Children.Add(myDockPanel);
myGrid.Children.Add(myStackPanel);
// Add the Grid as the Content of the Parent Window Object
mainWindow.Content = myGrid;
mainWindow.Show ();
'Add root Grid
Dim myGrid As New Grid
myGrid.Width = 175
myGrid.Height = 150
Dim myRowDef1 As New RowDefinition
Dim myRowDef2 As New RowDefinition
myGrid.RowDefinitions.Add(myRowDef1)
myGrid.RowDefinitions.Add(myRowDef2)
'Define the DockPanel
Dim myDockPanel As New DockPanel
Grid.SetRow(myDockPanel, 0)
'Define an Image and Source.
Dim myImage As New Image
Dim bi As New BitmapImage
bi.BeginInit()
bi.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi.EndInit()
myImage.Source = bi
Dim myImage2 As New Image
Dim bi2 As New BitmapImage
bi2.BeginInit()
bi2.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi2.EndInit()
myImage2.Source = bi2
Dim myImage3 As New Image
Dim bi3 As New BitmapImage
bi3.BeginInit()
bi3.UriSource = New Uri("smiley_stackpanel.PNG", UriKind.Relative)
bi3.EndInit()
myImage3.Stretch = Stretch.Fill
myImage3.Source = bi3
'Add the images to the parent DockPanel.
myDockPanel.Children.Add(myImage)
myDockPanel.Children.Add(myImage2)
myDockPanel.Children.Add(myImage3)
'Define a StackPanel.
Dim myStackPanel As New StackPanel
myStackPanel.Orientation = Orientation.Horizontal
Grid.SetRow(myStackPanel, 1)
Dim myImage4 As New Image
Dim bi4 As New BitmapImage
bi4.BeginInit()
bi4.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi4.EndInit()
myImage4.Source = bi4
Dim myImage5 As New Image
Dim bi5 As New BitmapImage
bi5.BeginInit()
bi5.UriSource = New Uri("smiley_stackpanel.png", UriKind.Relative)
bi5.EndInit()
myImage5.Source = bi5
Dim myImage6 As New Image
Dim bi6 As New BitmapImage
bi6.BeginInit()
bi6.UriSource = New Uri("smiley_stackpanel.PNG", UriKind.Relative)
bi6.EndInit()
myImage6.Stretch = Stretch.Fill
myImage6.Source = bi6
'Add the images to the parent StackPanel.
myStackPanel.Children.Add(myImage4)
myStackPanel.Children.Add(myImage5)
myStackPanel.Children.Add(myImage6)
'Add the layout panels as children of the Grid
myGrid.Children.Add(myDockPanel)
myGrid.Children.Add(myStackPanel)
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
WindowTitle="StackPanel vs. DockPanel">
<Grid Width="175" Height="150">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<DockPanel Grid.Column="0" Grid.Row="0">
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" Stretch="Fill"/>
</DockPanel>
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" />
<Image Source="smiley_stackpanel.png" Stretch="Fill"/>
</StackPanel>
</Grid>
</Page>
Der Unterschied beim Renderingverhalten kann in diesem Bild zu sehen sein.
Definieren und Verwenden eines StackPanel-Elements
Im folgenden Beispiel wird veranschaulicht, wie man eine Gruppe von vertikal positionierten Schaltflächen mit einem StackPanel erstellt. Legen Sie für die horizontale Positionierung die Orientation Eigenschaft auf Horizontal.
// Create the application's main window
mainWindow = new Window ();
mainWindow.Title = "StackPanel Sample";
// Define the StackPanel
myStackPanel = new StackPanel();
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;
// Define child content
Button myButton1 = new Button();
myButton1.Content = "Button 1";
Button myButton2 = new Button();
myButton2.Content = "Button 2";
Button myButton3 = new Button();
myButton3.Content = "Button 3";
// Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myStackPanel.Children.Add(myButton3);
// Add the StackPanel as the Content of the Parent Window Object
mainWindow.Content = myStackPanel;
mainWindow.Show ();
WindowTitle = "StackPanel Sample"
' Define the StackPanel
Dim myStackPanel As New StackPanel()
myStackPanel.HorizontalAlignment = Windows.HorizontalAlignment.Left
myStackPanel.VerticalAlignment = Windows.VerticalAlignment.Top
' Define child content
Dim myButton1 As New Button()
myButton1.Content = "Button 1"
Dim myButton2 As New Button()
myButton2.Content = "Button 2"
Dim myButton3 As New Button()
myButton3.Content = "Button 3"
' Add child elements to the parent StackPanel
myStackPanel.Children.Add(myButton1)
myStackPanel.Children.Add(myButton2)
myStackPanel.Children.Add(myButton3)
Me.Content = myStackPanel
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
VirtualizingStackPanel
WPF stellt außerdem eine Variante des StackPanel-Elements zur Verfügung, das automatisch datengebundenen untergeordneten Inhalt „virtualisiert“. In diesem Kontext bezieht sich das Wort virtualisieren auf eine Technik, mit der eine Teilmenge von Elementen aus einer größeren Anzahl von Datenelementen generiert wird, basierend darauf, welche Elemente auf dem Bildschirm sichtbar sind. Es ist sowohl speicher- als auch prozessorintensiv, eine große Anzahl von UI-Elementen zu generieren, wenn zu einem bestimmten Zeitpunkt nur wenige auf dem Bildschirm sind. VirtualizingStackPanel (durch von VirtualizingPanel bereitgestellte Funktionalität) berechnet sichtbare Elemente und funktioniert mit ItemContainerGenerator von ItemsControl (z. B ListBox oder ListView), um nur Elemente für sichtbare Objekte zu erstellen.
Das VirtualizingStackPanel-Element wird automatisch als Hostelement für Steuerungen wie die ListBox festgelegt. Beim Hosten einer datengebundenen Sammlung wird der Inhalt automatisch virtualisiert, solange er sich innerhalb der Grenzen eines ScrollViewer befindet. Dadurch wird die Leistung beim Hosten vieler untergeordneter Objekte erheblich verbessert.
Das folgende Markup veranschaulicht, wie ein VirtualizingStackPanel als Elemente-Host verwendet wird. Die VirtualizingStackPanel.IsVirtualizingProperty angefügte Eigenschaft muss für die Virtualisierung auf true
(Standard) festgelegt werden.
<StackPanel DataContext="{Binding Source={StaticResource Leagues}}">
<TextBlock Text="{Binding XPath=@name}" FontFamily="Arial" FontSize="18" Foreground="Black"/>
<ListBox VirtualizingStackPanel.IsVirtualizing="True"
ItemsSource="{Binding XPath=Team}"
ItemTemplate="{DynamicResource NameDataStyle}"/>
</StackPanel>
WrapPanel
WrapPanel wird verwendet, um untergeordnete Elemente in sequenzieller Position von links nach rechts zu positionieren, wobei der Inhalt in die nächste Zeile umgebrochen wird, wenn er den Rand des übergeordneten Containers erreicht. Inhalte können horizontal oder vertikal ausgerichtet werden. WrapPanel ist nützlich für einfache, fließende Benutzeroberflächenszenarien. Sie kann auch verwendet werden, um einheitliche Größenanpassungen auf alle untergeordneten Elemente anzuwenden.
Im folgenden Beispiel wird veranschaulicht, wie Sie ein WrapPanel erstellen, um Button Steuerelemente anzuzeigen, die umbrochen werden, wenn sie den Rand ihres Containers erreichen.
// Create the application's main window
mainWindow = gcnew System::Windows::Window();
mainWindow->Title = "WrapPanel Sample";
// Instantiate a new WrapPanel and set properties
myWrapPanel = gcnew WrapPanel();
myWrapPanel->Background = Brushes::Azure;
myWrapPanel->Orientation = Orientation::Horizontal;
myWrapPanel->ItemHeight = 25;
myWrapPanel->ItemWidth = 75;
myWrapPanel->Width = 150;
myWrapPanel->HorizontalAlignment = HorizontalAlignment::Left;
myWrapPanel->VerticalAlignment = VerticalAlignment::Top;
// Define 3 button elements. Each button is sized at width of 75, so the third button wraps to the next line.
btn1 = gcnew Button();
btn1->Content = "Button 1";
btn2 = gcnew Button();
btn2->Content = "Button 2";
btn3 = gcnew Button();
btn3->Content = "Button 3";
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel->Children->Add(btn1);
myWrapPanel->Children->Add(btn2);
myWrapPanel->Children->Add(btn3);
// Add the WrapPanel to the MainWindow as Content
mainWindow->Content = myWrapPanel;
mainWindow->Show();
// Create the application's main window
mainWindow = new System.Windows.Window();
mainWindow.Title = "WrapPanel Sample";
// Instantiate a new WrapPanel and set properties
myWrapPanel = new WrapPanel();
myWrapPanel.Background = System.Windows.Media.Brushes.Azure;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 200;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
// Define 3 button elements. The last three buttons are sized at width
// of 75, so the forth button wraps to the next line.
btn1 = new Button();
btn1.Content = "Button 1";
btn1.Width = 200;
btn2 = new Button();
btn2.Content = "Button 2";
btn2.Width = 75;
btn3 = new Button();
btn3.Content = "Button 3";
btn3.Width = 75;
btn4 = new Button();
btn4.Content = "Button 4";
btn4.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1);
myWrapPanel.Children.Add(btn2);
myWrapPanel.Children.Add(btn3);
myWrapPanel.Children.Add(btn4);
// Add the WrapPanel to the MainWindow as Content
mainWindow.Content = myWrapPanel;
mainWindow.Show();
WindowTitle = "WrapPanel Sample"
' Instantiate a new WrapPanel and set properties
Dim myWrapPanel As New WrapPanel()
myWrapPanel.Background = Brushes.Azure
myWrapPanel.Orientation = Orientation.Horizontal
myWrapPanel.Width = 200
myWrapPanel.HorizontalAlignment = Windows.HorizontalAlignment.Left
myWrapPanel.VerticalAlignment = Windows.VerticalAlignment.Top
' Define 3 button elements. The last three buttons are sized at width
' of 75, so the forth button wraps to the next line.
Dim btn1 As New Button()
btn1.Content = "Button 1"
btn1.Width = 200
Dim btn2 As New Button()
btn2.Content = "Button 2"
btn2.Width = 75
Dim btn3 As New Button()
btn3.Content = "Button 3"
btn3.Width = 75
Dim btn4 As New Button()
btn4.Content = "Button 4"
btn4.Width = 75
' Add the buttons to the parent WrapPanel using the Children.Add method.
myWrapPanel.Children.Add(btn1)
myWrapPanel.Children.Add(btn2)
myWrapPanel.Children.Add(btn3)
myWrapPanel.Children.Add(btn4)
' Add the WrapPanel to the Page as Content
Me.Content = myWrapPanel
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="WrapPanel Sample">
<Border HorizontalAlignment="Left" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="2">
<WrapPanel Background="LightBlue" Width="200" Height="100">
<Button Width="200">Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
<Button>Button 4</Button>
</WrapPanel>
</Border>
</Page>
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
Geschachtelte Panelelemente
Panel Elemente können miteinander verschachtelt werden, um komplexe Layouts zu erzeugen. Dies kann in Situationen, in denen ein Panel Teil einer Benutzeroberfläche ideal ist, sehr nützlich sein, aber möglicherweise nicht für einen anderen Teil der Benutzeroberfläche geeignet sein.
Es gibt keinen praktischen Grenzwert für die Menge der Schachtelung, die Ihre Anwendung unterstützen kann. Im Allgemeinen empfiehlt es sich jedoch, die Anwendung auf die Verwendung dieser Panels zu beschränken, die tatsächlich für ihr gewünschtes Layout erforderlich sind. In vielen Fällen kann ein Grid Element anstelle geschachtelter Panels aufgrund seiner Flexibilität als Layoutcontainer verwendet werden. Dies kann die Leistung in Ihrer Anwendung erhöhen, indem unnötige Elemente aus der Struktur heraushalten.
Im folgenden Beispiel wird veranschaulicht, wie Sie eine Benutzeroberfläche erstellen, die geschachtelte Panel Elemente nutzt, um ein bestimmtes Layout zu erzielen. In diesem speziellen Fall wird ein DockPanel-Element verwendet, um eine UI-Struktur bereitzustellen, und geschachtelte StackPanel-Elemente, ein Grid sowie ein Canvas werden verwendet, um untergeordnete Elemente genau innerhalb des übergeordneten DockPanel-Elements zu positionieren.
// Define the DockPanel.
myDockPanel = new DockPanel();
// Add the Left Docked StackPanel
Border myBorder2 = new Border();
myBorder2.BorderThickness = new Thickness(1);
myBorder2.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder2, Dock.Left);
StackPanel myStackPanel = new StackPanel();
Button myButton1 = new Button();
myButton1.Content = "Left Docked";
myButton1.Margin = new Thickness(5);
Button myButton2 = new Button();
myButton2.Content = "StackPanel";
myButton2.Margin = new Thickness(5);
myStackPanel.Children.Add(myButton1);
myStackPanel.Children.Add(myButton2);
myBorder2.Child = myStackPanel;
// Add the Top Docked Grid.
Border myBorder3 = new Border();
myBorder3.BorderThickness = new Thickness(1);
myBorder3.BorderBrush = Brushes.Black;
DockPanel.SetDock(myBorder3, Dock.Top);
Grid myGrid = new Grid();
myGrid.ShowGridLines = true;
RowDefinition myRowDef1 = new RowDefinition();
RowDefinition myRowDef2 = new RowDefinition();
ColumnDefinition myColDef1 = new ColumnDefinition();
ColumnDefinition myColDef2 = new ColumnDefinition();
ColumnDefinition myColDef3 = new ColumnDefinition();
myGrid.ColumnDefinitions.Add(myColDef1);
myGrid.ColumnDefinitions.Add(myColDef2);
myGrid.ColumnDefinitions.Add(myColDef3);
myGrid.RowDefinitions.Add(myRowDef1);
myGrid.RowDefinitions.Add(myRowDef2);
TextBlock myTextBlock1 = new TextBlock();
myTextBlock1.FontSize = 20;
myTextBlock1.Margin = new Thickness(10);
myTextBlock1.Text = "Grid Element Docked at the Top";
Grid.SetRow(myTextBlock1, 0);
Grid.SetColumnSpan(myTextBlock1, 3);
Button myButton3 = new Button();
myButton3.Margin = new Thickness(5);
myButton3.Content = "A Row";
Grid.SetColumn(myButton3, 0);
Grid.SetRow(myButton3, 1);
Button myButton4 = new Button();
myButton4.Margin = new Thickness(5);
myButton4.Content = "of Button";
Grid.SetColumn(myButton4, 1);
Grid.SetRow(myButton4, 1);
Button myButton5 = new Button();
myButton5.Margin = new Thickness(5);
myButton5.Content = "Elements";
Grid.SetColumn(myButton5, 2);
Grid.SetRow(myButton5, 1);
myGrid.Children.Add(myTextBlock1);
myGrid.Children.Add(myButton3);
myGrid.Children.Add(myButton4);
myGrid.Children.Add(myButton5);
myBorder3.Child = myGrid;
// Add the Bottom Docked StackPanel.
Border myBorder4 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder4.BorderThickness = new Thickness(1);
DockPanel.SetDock(myBorder4, Dock.Bottom);
StackPanel myStackPanel2 = new StackPanel();
myStackPanel2.Orientation = Orientation.Horizontal;
TextBlock myTextBlock2 = new TextBlock();
myTextBlock2.Text = "This StackPanel is Docked to the Bottom";
myTextBlock2.Margin = new Thickness(5);
myStackPanel2.Children.Add(myTextBlock2);
myBorder4.Child = myStackPanel2;
// Add the Canvas, that fills remaining space.
Border myBorder5 = new Border();
myBorder4.BorderBrush = Brushes.Black;
myBorder5.BorderThickness = new Thickness(1);
Canvas myCanvas = new Canvas();
myCanvas.ClipToBounds = true;
TextBlock myTextBlock3 = new TextBlock();
myTextBlock3.Text = "Content in the Canvas will Fill the remaining space.";
Canvas.SetTop(myTextBlock3, 50);
Canvas.SetLeft(myTextBlock3, 50);
Ellipse myEllipse = new Ellipse();
myEllipse.Height = 100;
myEllipse.Width = 125;
myEllipse.Fill = Brushes.CornflowerBlue;
myEllipse.Stroke = Brushes.Aqua;
Canvas.SetTop(myEllipse, 100);
Canvas.SetLeft(myEllipse, 150);
myCanvas.Children.Add(myTextBlock3);
myCanvas.Children.Add(myEllipse);
myBorder5.Child = myCanvas;
// Add child elements to the parent DockPanel.
myDockPanel.Children.Add(myBorder2);
myDockPanel.Children.Add(myBorder3);
myDockPanel.Children.Add(myBorder4);
myDockPanel.Children.Add(myBorder5);
Dim myDockPanel As New DockPanel()
Dim myBorder2 As New Border()
myBorder2.BorderThickness = New Thickness(1)
myBorder2.BorderBrush = Brushes.Black
DockPanel.SetDock(myBorder2, Dock.Left)
Dim myStackPanel As New StackPanel()
Dim myButton1 As New Button()
myButton1.Content = "Left Docked"
myButton1.Margin = New Thickness(5)
Dim myButton2 As New Button()
myButton2.Content = "StackPanel"
myButton2.Margin = New Thickness(5)
myStackPanel.Children.Add(myButton1)
myStackPanel.Children.Add(myButton2)
myBorder2.Child = myStackPanel
Dim myBorder3 As New Border()
myBorder3.BorderThickness = New Thickness(1)
myBorder3.BorderBrush = Brushes.Black
DockPanel.SetDock(myBorder3, Dock.Top)
Dim myGrid As New Grid()
myGrid.ShowGridLines = True
Dim myRowDef1 As New RowDefinition()
Dim myRowDef2 As New RowDefinition()
Dim myColDef1 As New ColumnDefinition()
Dim myColDef2 As New ColumnDefinition()
Dim myColDef3 As New ColumnDefinition()
myGrid.ColumnDefinitions.Add(myColDef1)
myGrid.ColumnDefinitions.Add(myColDef2)
myGrid.ColumnDefinitions.Add(myColDef3)
myGrid.RowDefinitions.Add(myRowDef1)
myGrid.RowDefinitions.Add(myRowDef2)
Dim myTextBlock1 As New TextBlock()
myTextBlock1.FontSize = 20
myTextBlock1.Margin = New Thickness(10)
myTextBlock1.Text = "Grid Element Docked at the Top"
Grid.SetRow(myTextBlock1, 0)
Grid.SetColumnSpan(myTextBlock1, 3)
Dim myButton3 As New Button()
myButton3.Margin = New Thickness(5)
myButton3.Content = "A Row"
Grid.SetColumn(myButton3, 0)
Grid.SetRow(myButton3, 1)
Dim myButton4 As New Button()
myButton4.Margin = New Thickness(5)
myButton4.Content = "of Button"
Grid.SetColumn(myButton4, 1)
Grid.SetRow(myButton4, 1)
Dim myButton5 As New Button()
myButton5.Margin = New Thickness(5)
myButton5.Content = "Elements"
Grid.SetColumn(myButton5, 2)
Grid.SetRow(myButton5, 1)
myGrid.Children.Add(myTextBlock1)
myGrid.Children.Add(myButton3)
myGrid.Children.Add(myButton4)
myGrid.Children.Add(myButton5)
myBorder3.Child = myGrid
Dim myBorder4 As New Border()
myBorder4.BorderBrush = Brushes.Black
myBorder4.BorderThickness = New Thickness(1)
DockPanel.SetDock(myBorder4, Dock.Bottom)
Dim myStackPanel2 As New StackPanel()
myStackPanel2.Orientation = Orientation.Horizontal
Dim myTextBlock2 As New TextBlock()
myTextBlock2.Text = "This StackPanel is Docked to the Bottom"
myTextBlock2.Margin = New Thickness(5)
myStackPanel2.Children.Add(myTextBlock2)
myBorder4.Child = myStackPanel2
Dim myBorder5 As New Border()
myBorder5.BorderBrush = Brushes.Black
myBorder5.BorderThickness = New Thickness(1)
Dim myCanvas As New Canvas()
myCanvas.ClipToBounds = True
Dim myTextBlock3 As New TextBlock()
myTextBlock3.Text = "Content in the Canvas will Fill the remaining space."
Canvas.SetTop(myTextBlock3, 50)
Canvas.SetLeft(myTextBlock3, 50)
Dim myEllipse As New Ellipse()
myEllipse.Height = 100
myEllipse.Width = 125
myEllipse.Fill = Brushes.CornflowerBlue
myEllipse.Stroke = Brushes.Aqua
Canvas.SetTop(myEllipse, 100)
Canvas.SetLeft(myEllipse, 150)
myCanvas.Children.Add(myTextBlock3)
myCanvas.Children.Add(myEllipse)
myBorder5.Child = myCanvas
myDockPanel.Children.Add(myBorder2)
myDockPanel.Children.Add(myBorder3)
myDockPanel.Children.Add(myBorder4)
myDockPanel.Children.Add(myBorder5)
Die kompilierte Anwendung liefert eine neue Benutzeroberfläche, die wie folgt aussieht.
Benutzerdefinierte Panelelemente
WPF stellt zwar ein Array flexibler Layout-Steuerelemente bereit, benutzerdefiniertes Layoutverhalten kann jedoch auch durch das Überschreiben der ArrangeOverride- und MeasureOverride-Methoden erreicht werden. Benutzerdefinierte Größenanpassung und Positionierung können erreicht werden, indem neue Positionierungsverhalten innerhalb dieser Außerkraftsetzungsmethoden definiert werden.
Ebenso können benutzerdefinierte Layoutverhalten basierend auf abgeleiteten Klassen (z Canvas . B. oder Grid) durch Überschreiben ihrer ArrangeOverride und MeasureOverride Methoden definiert werden.
Das folgende Markup veranschaulicht, wie ein benutzerdefiniertes Panel Element erstellt wird. Diese neue Panel, definiert als PlotPanel
, unterstützt die Positionierung untergeordneter Elemente durch die Verwendung hartcodierter x-Koordinaten und y-Koordinaten. In diesem Beispiel wird ein Rectangle Element (nicht dargestellt) am Zeichnungspunkt 50 (x) und 50 (y) positioniert.
public:
ref class PlotPanel : Panel {
public:
PlotPanel () {};
protected:
// Override the default Measure method of Panel
virtual Size MeasureOverride(Size availableSize) override
{
Size^ panelDesiredSize = gcnew Size();
// In our example, we just have one child.
// Report that our panel requires just the size of its only child.
for each (UIElement^ child in InternalChildren)
{
child->Measure(availableSize);
panelDesiredSize = child->DesiredSize;
}
return *panelDesiredSize ;
}
protected:
virtual System::Windows::Size ArrangeOverride (Size finalSize) override
{
for each (UIElement^ child in InternalChildren)
{
double x = 50;
double y = 50;
child->Arrange(Rect(Point(x, y), child->DesiredSize));
}
return finalSize;
};
};
public class PlotPanel : Panel
{
// Default public constructor
public PlotPanel()
: base()
{
}
// Override the default Measure method of Panel
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();
// In our example, we just have one child.
// Report that our panel requires just the size of its only child.
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
panelDesiredSize = child.DesiredSize;
}
return panelDesiredSize ;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
double x = 50;
double y = 50;
child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
}
return finalSize; // Returns the final Arranged size
}
}
Public Class PlotPanel
Inherits Panel
'Override the default Measure method of Panel.
Protected Overrides Function MeasureOverride(ByVal availableSize As System.Windows.Size) As System.Windows.Size
Dim panelDesiredSize As Size = New Size()
' In our example, we just have one child.
' Report that our panel requires just the size of its only child.
For Each child As UIElement In InternalChildren
child.Measure(availableSize)
panelDesiredSize = child.DesiredSize
Next
Return panelDesiredSize
End Function
Protected Overrides Function ArrangeOverride(ByVal finalSize As System.Windows.Size) As System.Windows.Size
For Each child As UIElement In InternalChildren
Dim x As Double = 50
Dim y As Double = 50
child.Arrange(New Rect(New System.Windows.Point(x, y), child.DesiredSize))
Next
Return finalSize
End Function
End Class
Um eine komplexere Implementierung eines benutzerdefinierten Panels zu sehen, schauen Sie sich die Beispielanwendung Ein benutzerdefiniertes Inhaltsumschlagpanel erstellen an.
Lokalisierungs-/Globalisierungsunterstützung
WPF unterstützt eine Reihe von Features, die bei der Erstellung lokalisierbarer Ui unterstützen.
Alle Panelelemente unterstützen nativ die FlowDirection Eigenschaft, die verwendet werden kann, um Inhalte dynamisch basierend auf den Spracheinstellungen eines Benutzers neu zu formatieren. Weitere Informationen finden Sie unter FlowDirection.
Die SizeToContent Eigenschaft bietet einen Mechanismus, mit dem Anwendungsentwickler die Anforderungen der lokalisierten Benutzeroberfläche antizipieren können. Wenn Sie den WidthAndHeight Wert dieser Eigenschaft verwenden, passt sich ein übergeordnetes Window-Element immer dynamisch dem Inhalt an und wird nicht durch künstliche Höhen- oder Breitenbeschränkungen eingeschränkt.
DockPanel, Gridund StackPanel sind alle gute Auswahlmöglichkeiten für lokalisierbare UI. Canvas ist jedoch keine gute Wahl, da sie Inhalte absolut positioniert, was es schwierig macht, zu lokalisieren.
Weitere Informationen zum Erstellen von WPF-Anwendungen mit lokalisierbaren Benutzeroberflächen (UIs) finden Sie in der Übersicht über die Verwendung des automatischen Layouts.
Siehe auch
- Exemplarische Vorgehensweise: Meine erste WPF-Desktopanwendung
- Beispiel für einen WPF-Layoutkatalog
- Layout
- Katalogbeispiel eines WPF-Steuerelements
- Übersicht über Alignment, Margin und Padding
- Beispiel für ein benutzerdefiniertes Inhalts-Wrapper-Panel erstellen
- Übersicht über angefügte Eigenschaften
- Übersicht über die Verwendung eines automatischen Layouts
- Layout und Entwurf
.NET Desktop feedback