Übersicht über Panel-Elemente

Panel-Elemente sind Komponenten, die das Rendern von Elementen steuern, d. h. ihre Größe und Abmessungen, Ihre Position und die Anordnung des untergeordneten Inhalts. Windows Presentation Foundation (WPF) bietet eine Anzahl vordefinierter Panel-Elemente sowie die Möglichkeit, benutzerdefinierte Panel-Elemente zu erstellen.

Dieses Thema enthält folgende Abschnitte.

  • Panel-Klasse

  • Allgemeine Member des Panel-Elements

  • Abgeleitete Panel-Elemente

  • Panel-Elemente für Benutzeroberflächen

  • Geschachtelte Panel-Elemente

  • Benutzerdefinierte Panel-Elemente

  • Unterstützung der Lokalisierung/Globalisierung

  • Verwandte Themen

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.

WPF enthält eine umfassende Suite von abgeleiteten Panel-Implementierungen, mit denen eine Vielzahl komplexer Layouts möglich sind. Diese abgeleiteten Klassen machen Eigenschaften und Methoden verfügbar, die die meisten Standard-user interface (UI)-Szenarien ermöglichen. Entwickler, die kein Verhalten für das Anordnen untergeordneter Elemente finden können, das ihren Anforderungen entspricht, können neue Layouts erstellen, indem sie die ArrangeOverride-Methode und die MeasureOverride-Methode überschreiben. Weitere Informationen über das Verhalten benutzerdefinierter Layouts finden Sie unter Benutzerdefinierte Panel-Elemente.

Allgemeine Member von Panel

Alle Panel-Elemente unterstützen die grundlegenden Skalierungs- und Positionierungseigenschaften, die von FrameworkElement definiert werden, einschließlich Height, Width, HorizontalAlignment, VerticalAlignment, Margin und LayoutTransform. Weitere Informationen über die von FrameworkElement definierten Positionierungseigenschaften finden Sie unter Übersicht über Alignment, Margin und Padding.

Panel macht zusätzliche Eigenschaften verfügbar, die für das Verständnis und die Verwendung des Layouts besonders wichtig sind. Die Background-Eigenschaft wird verwendet, um den Bereich zwischen den Grenzen eines abgeleiteten Panel-Elements mit einem Brush zu füllen. Children stellt die Auflistung untergeordneter Elemente von Elementen dar, aus denen das Panel-Objekt besteht. InternalChildren stellt den Inhalt der Children-Auflistung zuzüglich der Member dar, die durch Datenbindung generiert wurden. Beide bestehen aus einer UIElementCollection untergeordneter Elemente, die im übergeordneten Panel gehostet werden.

Panel macht auch eine angefügte Panel.ZIndex-Eigenschaft verfügbar, die verwendet werden kann, um in einem abgeleiteten Panel Elemente überlagernd anzuordnen. Die Member der Children-Auflistung eines Panel-Elements, die einen höheren Panel.ZIndex-Wert haben, werden vor den Membern mit einem niedrigeren Panel.ZIndex-Wert angezeigt. Dies bietet sich besonders für Panel-Elemente wie Canvas und Grid an, bei denen untergeordnete Elemente denselben Koordinatenraum gemeinsam nutzen können.

Panel definiert auch die OnRender-Methode, die verwendet werden kann, um das Standard-Anzeigeverhalten für ein Panel-Element zu überschreiben.

Angefügte Eigenschaften

Abgeleitete Panel-Elemente machen umfassenden Gebrauch von angefügten Eigenschaften. Eine angefügte Eigenschaft ist eine Sonderform der Abhängigkeitseigenschaft, die nicht den konventionellen common language runtime (CLR)-Eigenschaftenwrapper besitzt. Angefügte Eigenschaften haben eine besondere Syntax in Extensible Application Markup Language (XAML), die in mehreren der folgenden Beispiele veranschaulicht wird.

Ein Zweck einer angefügten Eigenschaft besteht darin, es den untergeordneten Elementen zu ermöglichen, eindeutige Werte einer Eigenschaft zu speichern, die tatsächlich durch ein übergeordnetes Element definiert wird. Diese Funktion wird z. B. dann angewendet, wenn untergeordnete Elemente übergeordnete Elemente darüber informieren sollen, wie sie in der user interface (UI) angezeigt werden. Dies ist für das Anwendungslayout sehr nützlich. Weitere Informationen finden Sie unter Übersicht über angefügte Eigenschaften.

Abgeleitete Panel-Elemente

Viele Objekte werden von Panel abgeleitet, aber nicht alle sind für die Verwendung als Stammlayoutanbieter ausgelegt. Es gibt sechs definierte Panel-Klassen (Canvas, DockPanel, Grid, StackPanel, VirtualizingStackPanel und WrapPanel), die speziell für das Erstellen von Anwendungs-UI vorgesehen sind.

Jedes Panel-Element kapselt seine eigene besondere Funktionalität, wie in der folgenden Tabelle gezeigt wird.

Elementname

Benutzeroberflächen-Panel?

Beschreibung

Canvas

Ja

Definiert einen Bereich, in dem Sie untergeordnete Elemente explizit mithilfe von Koordinaten positionieren können, die relativ zum Canvas-Bereich sind.

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 Grid-Elements können mit der Margin-Eigenschaft genau positioniert werden.

StackPanel

Ja

Ordnet untergeordnete Elemente in einer einzelnen Zeile an, die horizontal oder vertikal ausgerichtet sein kann.

TabPanel

Nein

Behandelt das Layout von Registerkartenschaltflächen in einem TabControl.

ToolBarOverflowPanel

Nein

Ordnet Inhalt innerhalb eines ToolBar-Steuerelements an.

UniformGrid

Nein

UniformGrid wird verwendet, um untergeordnete Elemente in einem Raster mit gleich großen Zellen anzuordnen.

VirtualizingPanel

Nein

Stellt eine Basisklasse für Panel-Elemente bereit, die ihre Auflistung untergeordneter Elemente "virtualisieren" können.

VirtualizingStackPanel

Ja

Ordnet Inhalt an und virtualisiert Inhalt in einer einzelnen Zeile mit horizontaler oder vertikaler Ausrichtung.

WrapPanel

Ja

WrapPanel positioniert untergeordnete Elemente nacheinander von links nach rechts und bricht den Inhalt am Rand des enthaltenden Felds in die nächste Zeile um. Je nach dem Wert der Orientation-Eigenschaft erfolgt die weitere Anordnung nacheinander von oben nach unten oder von rechts nach links.

Panel-Elemente für Benutzeroberflächen

In WPF stehen sechs Panel-Klassen zur Verfügung, die für die Unterstützung von UI-Szenarien optimiert sind: Canvas, DockPanel, Grid, StackPanel, VirtualizingStackPanel und WrapPanel. Diese Panel-Elemente sind einfach zu verwenden, vielseitig und können für die meisten Anwendungen ausreichend erweitert werden.

Jedes abgeleitete Panel-Element behandelt Einschränkungen für die Größenanpassung unterschiedlich. Wenn Sie wissen, wie ein Panel Einschränkungen in der horizontalen oder vertikalen Richtung behandelt, kann dies das Layout vorhersagbarer machen.

Panel-Name

x-Dimension

y-Dimension

Canvas

Eingeschränkt auf Inhalt

Eingeschränkt auf Inhalt

DockPanel

Eingeschränkt

Eingeschränkt

StackPanel (vertikale Ausrichtung)

Eingeschränkt

Eingeschränkt auf Inhalt

StackPanel (horizontale Ausrichtung)

Eingeschränkt auf Inhalt

Eingeschränkt

Grid

Eingeschränkt

Eingeschränkt, außer in Fällen, in denen Auto für Zeilen und Spalten gilt

WrapPanel

Eingeschränkt auf Inhalt

Eingeschränkt auf Inhalt

Nachstehend finden Sie ausführlichere Beschreibungen und Verwendungsbeispiele für jedes dieser Elemente.

Canvas

Das Canvas-Element ermöglicht die Positionierung des Inhalts entsprechend absoluten x--Koordinaten und y-Koordinaten. Elemente können an einer bestimmten Stelle gezeichnet werden. Wenn Elemente dieselben Koordinaten verwenden, bestimmt die Reihenfolge, in der sie im Markup erscheinen, die Reihenfolge, in der die Elemente gezeichnet werden.

Canvas ist das Panel-Element mit der flexibelsten Layoutunterstützung. Die Eigenschaften Height und Width werden verwendet, um den Bereich des Canvas zu definieren, und den darin enthaltenen Elementen werden absolute Koordinaten zugewiesen, die relativ zum Bereich des übergeordneten Canvas sind. Mit den vier angehängten Eigenschaften Canvas.Left, Canvas.Top, Canvas.Right und Canvas.Bottom können Sie die Platzierung von Objekten in einem Canvas genau steuern. Dies ermöglicht es dem Entwickler, Elemente auf dem Bildschirm präzise zu platzieren und anzuordnen.

ClipToBounds innerhalb eines Canvas

Canvas kann untergeordnete Elemente an jeder beliebigen Position auf dem Bildschirm platzieren, selbst bei Koordinaten, die sich außerhalb der eigenen definierten Height und Width befinden. Canvas wird auch nicht von der Größe seiner untergeordneten Elemente beeinflusst. Aus diesem Grund ist es für ein untergeordnetes Element möglich, andere Elemente außerhalb des umgebenden Rechtecks des übergeordneten Canvas zu überschreiben. Das Standardverhalten eines Canvas besteht darin, das Zeichnen untergeordneter Elemente außerhalb des umgebenden Rechtecks des übergeordneten Canvas zu ermöglichen. Wenn dieses Verhalten unerwünscht ist, kann die ClipToBounds-Eigenschaft auf true festgelegt werden. Dadurch wird Canvas auf seine eigene Größe beschnitten. Canvas ist das einzige Layoutelement, das das Zeichnen untergeordneter Elemente außerhalb seiner Grenzen ermöglicht.

Dieses Verhalten wird im Beispiel für den Vergleich von Breiteneigenschaften grafisch veranschaulicht.

Definieren und Verwenden eines Canvas

Ein Canvas kann instanziiert werden, indem man einfach Extensible Application Markup Language (XAML) oder Code verwendet. Im folgenden Beispiel wird veranschaulicht, wie Canvas verwendet wird, um Inhalt absolut zu positionieren. Dieser Code erzeugt drei Quadrate mit einer Seitenlänge von 100 Pixeln. Das erste Quadrat ist rot, und die obere linke (x, y)-Position ist als (0, 0) festgelegt. Das zweite Quadrat ist grün, und die obere linke Position ist (100, 100) und befindet sich etwas unterhalb und rechts des ersten Quadrats. Das dritte Quadrat ist blau, und die obere linke Position ist (50, 50). Es umfasst daher den unteren rechten Quadranten des ersten Quadrats und den oberen linken Quadranten des zweiten Quadrats. Da das dritte Quadrat zuletzt angeordnet wird, scheint es über den beiden anderen Quadraten zu liegen. Die sich überschneidenden Teile nehmen also die Farbe des dritten Quadrats an.

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

            // 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 ();

<Page WindowTitle="Canvas Sample" xmlns="https://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 ergibt eine neue UI, die folgendermaßen aussieht.

Ein typisches Canvas-Element.

DockPanel

Das DockPanel-Element verwendet die angefügte DockPanel.Dock-Eigenschaft, wie in den untergeordneten Inhaltselementen festgelegt ist, um Inhalt an den Rändern eines Containers zu positionieren. Wenn DockPanel.Dock auf Top oder Bottom festgelegt wird, werden untergeordnete Elemente übereinander oder untereinander positioniert. Wenn DockPanel.Dock auf Left oder Right festgelegt wird, werden untergeordnete Elemente links oder rechts voneinander positioniert. Die LastChildFill-Eigenschaft bestimmt die Position des letzten Elements, das als untergeordnetes Element von einem DockPanel-Element hinzugefügt wird.

Sie können das DockPanel-Element verwenden, um eine Gruppe verwandter Steuerelemente zu positionieren, z. B. eine Reihe von Schaltflächen. Sie können es auch verwenden, um eine UI mit Panel-Elementen zu erstellen, die der Benutzeroberfläche in Microsoft Outlook ähnelt.

Größenanpassung an den Inhalt

Wenn die Height-Eigenschaft und die Width-Eigenschaft nicht angegeben werden, passt DockPanel seine Größe dem Inhalt an. Der Inhalt kann je nach der Größe der untergeordneten Elemente größer oder kleiner sein. Wenn diese Eigenschaften jedoch festgelegt sind und für das nächste angegebene untergeordnete Element kein Platz mehr vorhanden ist, zeigt DockPanel dieses untergeordnete Element und weitere untergeordnete Elemente nicht an und misst die folgenden untergeordneten Elemente nicht.

LastChildFill

In den Standardeinstellungen füllt das letzte untergeordnete Element eines DockPanel-Elements den übrigen verfügbaren Platz aus. Wenn dieses Verhalten unerwünscht ist, legen Sie die LastChildFill-Eigenschaft auf false fest.

Definieren und Verwenden eines DockPanel-Elements

Im folgenden Beispiel wird veranschaulicht, wie Bereiche mit einem DockPanel-Element aufgeteilt werden. Fünf Border-Elemente werden als untergeordnete Elemente eines übergeordneten DockPanel-Elements hinzugefügt. Jedes Element verwendet eine andere Positionierungseigenschaft eines DockPanel-Elements, um einen Bereich aufzuteilen. Das letzte Element "füllt" den verbleibenden verfügbaren Bereich aus.

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

            // 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 ();


         // 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();

<Page xmlns="https://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 ergibt eine neue UI, die folgendermaßen aussieht.

Ein typisches DockPanel-Szenario.

Raster

Das Grid-Element führt die Funktionen eines Steuerelements für die absolute Positionierung und eines Tabellendaten-Steuerelements zusammen. Mit einem Grid können Sie Elemente problemlos positionieren und formatieren. Grid ermöglicht es Ihnen, flexible Gruppen von Zeilen und Spalten zu definieren. Dieses Element enthält sogar einen Mechanismus, durch den mehrere Grid-Elemente die Größeninformationen gemeinsam nutzen können.

Was unterscheidet ein Raster von einer Tabelle?

Table und Grid haben einige allgemeine Funktionen gemeinsam, sind jedoch beide für unterschiedliche Szenarien geeignet. Eine Table ist für die Verwendung innerhalb von fortlaufenden Inhalten vorgesehen. (Weitere Informationen über fortlaufenden Inhalt finden Sie unter Übersicht über Flussdokumente.) Raster eignen sich am besten für die Verwendung in Formularen (bzw. außerhalb von fortlaufendem Inhalt). In einem FlowDocument unterstützt eine Table verschiedene Verhaltensweisen von fortlaufendem Inhalt wie Paginierung, Tabellenflussrichtung und Inhaltsauswahl, ein Grid dagegen unterstützt dies nicht. Ein Grid sollte aus verschiedenen Gründen außerhalb eines FlowDocument verwendet werden. Unter anderem fügt ein Grid im Gegensatz zu einer Table Elemente auf Grundlage eines Zeilen- und Spaltenindexes hinzu. Das Grid-Element ermöglicht es, untergeordnete Inhalte überlagernd anzuordnen, sodass mehrere Elemente in einer "Zelle" enthalten sein können. Table unterstützt die Überlagerung nicht. Die untergeordneten Elemente für ein Grid-Element können absolut zum Bereich ihrer Zellenbegrenzung positioniert werden. Table unterstützt dieses Feature nicht. Ein Grid ist weniger umfangreich als eine Table.

Größenanpassungsverhalten von Spalten und Zeilen

Für die in einem Grid definierten Spalten und Zeilen können die Vorteile der Star-Größenanpassung genutzt werden, um den verbleibenden Platz proportional zu verteilen. Wenn Star als Höhe oder Breite einer Zeile oder Spalte ausgewählt wurde, erhält diese Spalte oder Zeile eine gewichtete Proportion des verbleibenden verfügbaren Platzes. Im Gegensatz dazu wird bei Auto der Platz gleichmäßig auf Grundlage der Größe des Inhalts in einer Spalte oder Zeile verteilt. Dieser Wert wird als * oder 2* angegeben, wenn Sie Extensible Application Markup Language (XAML) verwenden. Im ersten Fall wird der Zeile oder Spalte der verfügbare Platz genau einmal zugeordnet, im zweiten Fall wird der verfügbare Platz zweimal zugeordnet usw. Durch Kombinieren dieser Technik für das gleichmäßige Verteilen des Platzes mit dem Wert Stretch für HorizontalAlignment und VerticalAlignment ist es möglich, den Layoutplatz nach dem Prozentsatz der Bildschirmfläche aufzuteilen. Grid ist der einzige Layoutbereich, der den Platz auf diese Weise aufteilen kann.

Definieren und Verwenden eines Rasters

Im folgenden Beispiel wird gezeigt, wie Sie eine UI erstellen, die dem im Startmenü von Windows verwendeten Dialogfeld Ausführen ähnelt.


'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

// 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;
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      WindowTitle="Grid Run Dialog Sample" 
      WindowWidth="425" 
      WindowHeight="225">
  <Grid Background="#DCDCDC"
        Width="425"
        Height="165"
        HorizontalAlignment="Left"
        VerticalAlignment="Top"
        ShowGridLines="True">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition Width="*" />
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Image Grid.Column="0" Grid.Row="0" Source="RunIcon.png" />
    <TextBlock Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="0" TextWrapping="Wrap">
      Type the name of a program, folder, document, or
      Internet resource, and Windows will open it for you.
    </TextBlock>
    <TextBlock Grid.Column="0" Grid.Row="1">Open:</TextBlock>
    <TextBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="5" />
    <Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="2">OK</Button>
    <Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="3">Cancel</Button>
    <Button Margin="10, 0, 10, 15" Grid.Row="3" Grid.Column="4">Browse ...</Button>
  </Grid>
</Page>

Die kompilierte Anwendung ergibt eine neue UI, die folgendermaßen aussieht.

Ein typisches Rasterelement.

StackPanel

Ein StackPanel-Element ermöglicht es Ihnen, Elemente in einer zugewiesenen Richtung zu "stapeln". Standardmäßig ist die Stapelrichtung vertikal. Sie können den fortlaufenden Inhalt mithilfe der Orientation-Eigenschaft steuern.

StackPanel im Vergleich zuDockPanel

Obwohl DockPanel ebenfalls zum Stapeln von untergeordneten Elementen verwendet werden kann, führen DockPanel und StackPanel in manchen Szenarien nicht immer zu gleichen Ergebnissen. Beispielsweise kann in einem DockPanel-Element die Reihenfolge der untergeordneten Elemente ihre Größe beeinflussen. In einem StackPanel-Element ist das jedoch nicht der Fall. Dies liegt daran, dass das StackPanel-Element in Stapelrichtung bei PositiveInfinity misst, wohingegen das DockPanel-Element nur die verfügbare Größe misst.

Im folgenden Beispiel wird dieser wichtige Unterschied veranschaulicht.


            '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)


            // 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 ();


         // 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();

<Page xmlns="https://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>

Dieses Bild zeigt den Unterschied im Renderingverhalten.

Bildschirmabbildung: StackPanel im Vergleich zu DockPanel

Definieren und Verwenden eines StackPanel-Elements

Im folgenden Beispiel wird veranschaulicht, wie mit einem StackPanel-Element eine Reihe vertikal positionierter Schaltflächen erstellt wird. Legen Sie die Orientation-Eigenschaft auf Horizontal fest, um eine horizontale Positionierung zu erzielen.

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

            // 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 ();

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="StackPanel Sample">
    <StackPanel HorizontalAlignment="Left"
                VerticalAlignment="Top">
        <Button>Button 1</Button>
        <Button>Button 2</Button>
        <Button>Button 3</Button>
    </StackPanel>
</Page>

Die kompilierte Anwendung ergibt eine neue UI, die folgendermaßen aussieht.

Ein typisches StackPanel-Element.

VirtualizingStackPanel

WPF stellt außerdem eine Variante des StackPanel-Elements bereit, das datengebundenen untergeordneten Inhalt automatisch "virtualisiert". In diesem Zusammenhang bezeichnet "virtualisieren" eine Vorgehensweise, bei der eine Teilmenge von Elementen aus einer größeren Anzahl von Datenelementen generiert wird, wobei berücksichtigt wird, welche Elemente auf dem Bildschirm angezeigt werden. Das Generieren einer großen Anzahl von Benutzeroberflächenelementen nimmt sehr viel Arbeitsspeicher und Prozessorleistung in Anspruch, auch wenn jeweils nur einige der Elemente auf dem Bildschirm angezeigt werden. VirtualizingStackPanel (mithilfe der Funktionen von VirtualizingPanel) berechnet die sichtbaren Elemente und erstellt dann zusammen mit dem ItemContainerGenerator aus einem ItemsControl (z. B. einem ListBox oder einer ListView) nur die Elemente für die sichtbaren Elemente

Das VirtualizingStackPanel-Element wird automatisch als Elementhost für Steuerelemente wie das ListBox festgelegt. Wenn eine datengebundene Auflistung gehostet wird, wird der Inhalt automatisch virtualisiert, solange der Inhalt sich innerhalb der Grenzen eines ScrollViewer-Elements befindet. Dadurch wird die Leistung beim Hosten vieler untergeordneter Elemente erheblich verbessert.

Das folgende Markup veranschaulicht, wie ein VirtualizingStackPanel-Element als Elementhost verwendet wird. Die angehängte VirtualizingStackPanel.IsVirtualizing -Eigenschaft muss auf true (Standard) festgelegt werden, damit die Virtualisierung ausgeführt wird.

<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 nacheinander von links nach rechts zu positionieren, wobei der Inhalt in die nächste Zeile umbrochen wird, sobald der Rand des übergeordneten Containers erreicht wird. Der Inhalt kann horizontal oder vertikal ausgerichtet werden. WrapPanel eignet sich für einfache Szenarien mit fließender user interface (UI). WrapPanel kann auch verwendet werden, um eine einheitliche Größe auf alle untergeordneten Elemente anzuwenden.

Das folgende Beispiel veranschaulicht, wie ein WrapPanel-Element erstellt wird, um Button-Steuerelemente anzuzeigen, die umbrochen werden, wenn sie den Rand des Containers erreichen.

            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


            // 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();


         // 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();

<Page xmlns="https://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 ergibt eine neue UI, die folgendermaßen aussieht.

Ein typisches WrapPanel-Element.

Geschachtelte Panel-Elemente

Panel-Elemente können ineinander geschachtelt werden, um komplexe Layouts zu erzeugen. Dies kann sich in Situationen als sehr nützlich erweisen, in denen ein Panel-Element für einen Teil der UI geeignet ist, aber möglicherweise nicht die Anforderungen eines anderen Teils der UI erfüllt.

Es gibt praktisch keine Begrenzung für die Anzahl der Schachtelungen, die Ihre Anwendung unterstützen kann. Es empfiehlt sich jedoch, in Ihrer Anwendung nur die Panel-Elemente zu verwenden, die für das gewünschte Layout tatsächlich notwendig sind. In vielen Fällen kann ein Grid-Element statt geschachtelter Panel-Elemente verwendet werden, da es als Layoutcontainer flexibel ist. Dies kann die Leistung der Anwendung erhöhen, da keine unnötigen Elemente in der Struktur verwendet werden.

Das folgende Beispiel veranschaulicht, wie eine UI erstellt wird, die geschachtelte Panel-Elemente nutzt, um ein bestimmtes Layout zu erzielen. In diesem speziellen Fall wird ein DockPanel-Element verwendet, um die UI-Struktur bereitzustellen. Geschachtelte StackPanel-Elemente, ein Grid und ein Canvas werden verwendet, um untergeordnete Elemente im übergeordneten DockPanel-Element genau zu positionieren.

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)

// 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);
<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" WindowTitle="Nested Panels">
  <Border Background="AliceBlue" 
          Width="400" 
          Height="300" 
          BorderBrush="DarkSlateBlue" 
          BorderThickness="2"
          HorizontalAlignment="Left" 
          VerticalAlignment="Top">
    <DockPanel>
      <Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Left">
        <StackPanel>
          <Button Margin="5">Left Docked</Button>
          <Button Margin="5">StackPanel</Button>
        </StackPanel>
      </Border>
      <Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Top">
        <Grid ShowGridLines="True">
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
          </Grid.ColumnDefinitions>
          <TextBlock FontSize="20" Margin="10" Grid.ColumnSpan="3" Grid.Row="0">Grid Element Docked to the Top.</TextBlock>
          <Button Grid.Row="1" Grid.Column="0" Margin="5">A Row</Button>
          <Button Grid.Row="1" Grid.Column="1" Margin="5">of Button</Button>
          <Button Grid.Row="1" Grid.Column="2" Margin="5">Elements</Button>
        </Grid>
      </Border>
      <Border BorderBrush="Black" BorderThickness="1" DockPanel.Dock="Bottom">
        <StackPanel Orientation="Horizontal">
          <TextBlock Margin="5">This StackPanel is Docked to the Bottom.</TextBlock>
        </StackPanel>
      </Border>
      <Border BorderBrush="Black" BorderThickness="1">
        <Canvas ClipToBounds="True">
          <TextBlock Canvas.Top="50" Canvas.Left="50">
            Content in the Canvas will Fill the remaining Space.
          </TextBlock>
          <Ellipse Height="100" Width="125" Fill="CornflowerBlue" Stroke="Aqua" Canvas.Top="100" Canvas.Left="150"/>
        </Canvas>
      </Border>
    </DockPanel>
  </Border>
</Page>

Die kompilierte Anwendung ergibt eine neue UI, die folgendermaßen aussieht.

Eine UI, die verschachtelte Bereiche nutzt.

Benutzerdefinierte Panel-Elemente

Während WPF ein Array von flexiblen Layout-Steuerelementen bereitstellt, kann benutzerdefiniertes Layoutverhalten auch erzielt werden, indem die ArrangeOverride-Methode und die MeasureOverride-Methode überschrieben werden. Benutzerdefinierte Größenanpassung und Positionierung kann auch ermöglicht werden, indem neue Positionierungsverhalten innerhalb dieser Überschreibungsmethoden definiert werden.

Auf ähnliche Weise können benutzerdefinierte Layoutverhalten, die auf abgeleiteten Klassen basieren (z. B. Canvas oder Grid) definiert werden, indem die zugehörige ArrangeOverride-Methode und die MeasureOverride-Methode überschrieben werden.

Das folgende Markup veranschaulicht, wie ein benutzerdefiniertes Panel-Element erstellt wird. Dieses neue Panel-Element, definiert als PlotPanel, unterstützt die Positionierung von untergeordneten Elementen durch Verwendung von hartcodierten x- und y-Koordinaten. In diesem Beispiel wird ein Rectangle-Element (nicht angezeigt) am Zeichnungspunkt 50 (x) und 50 (y) positioniert.

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
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: 
      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;
         };
      };

Eine komplexere Implementierung von benutzerdefinierten Panel-Elementen finden Sie unter Erstellen eines Beispiels für einen Bereich mit benutzerdefiniertem Inhaltsumbruch.

Unterstützung der Lokalisierung/Globalisierung

WPF unterstützt eine Anzahl von Features, die Ihnen bei der Erstellung einer lokalisierbaren UI helfen.

Alle Panel-Elemente unterstützen direkt die FlowDirection-Eigenschaft, mit der Inhalt dynamisch neu aufgebaut werden kann, der auf dem Gebietsschema oder den Spracheinstellungen eines Benutzers basiert. Weitere Informationen finden Sie unter FlowDirection.

Die SizeToContent-Eigenschaft stellt einen Mechanismus bereit, der es Anwendungsentwicklern ermöglicht, die Anforderungen lokalisierter UI einzuschätzen. Mithilfe des WidthAndHeight-Werts dieser Eigenschaft wird die Größe für ein übergeordnetes Window immer dynamisch an den Inhalt angepasst und ist nicht durch künstliche Höhen- oder Breitenangaben eingeschränkt.

DockPanel, Grid und StackPanel sind geeignete Elemente für eine lokalisierbare UI. Canvas ist nicht geeignet, da der Inhalt absolut positioniert wird und damit die Lokalisierung schwierig ist.

Weitere Informationen über das Erstellen von WPF-Anwendungen mit lokalisierbarer user interfaces (UIs) finden Sie unter Übersicht über die Verwendung eines automatischen Layouts.

Siehe auch

Konzepte

Exemplarische Vorgehensweise: Erste Schritte mit WPF

Layoutsystem

Übersicht über Alignment, Margin und Padding

Übersicht über angefügte Eigenschaften

Übersicht über die Verwendung eines automatischen Layouts

Optimieren der Leistung: Layout und Entwurf

Weitere Ressourcen

Beispiel für einen WPF-Layoutkatalog

Beispiel für WPF-Steuerelementsammlungen

Erstellen eines Beispiels für einen Bereich mit benutzerdefiniertem Inhaltsumbruch

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

Juli 2010

Das Beispiel im Abschnitt "WrapPanel" wurde korrigiert.

Kundenfeedback.