Initialisierung für Objektelemente außerhalb einer Objektstruktur
Einige Aspekte der Windows Presentation Foundation (WPF)-Initialisierung werden für Prozesse zurückgestellt, für die es normalerweise erforderlich ist, dass das Element entweder mit der logischen Struktur oder der visuellen Struktur verbunden ist. In diesem Thema sind die Schritte beschrieben, die ggf. erforderlich sind, um ein Element initialisieren zu können, das nicht mit einer dieser Strukturen verbunden ist.
Dieses Thema enthält folgende Abschnitte.
- Elemente und die logische Struktur
- Verwandte Abschnitte
Elemente und die logische Struktur
Beim Erstellen einer Instanz einer Windows Presentation Foundation (WPF)-Klasse im Code sollten Sie beachten, dass mehrere Aspekte der Objektinitialisierung für eine Windows Presentation Foundation (WPF)-Klasse absichtlich nicht Teil des Codes sind, der beim Aufrufen des Klassenkonstruktors ausgeführt wird. Besonders im Falle einer Steuerelementklasse wird der größte Teil der visuellen Darstellung des Steuerelements nicht über den Konstruktor definiert. Stattdessen wird die visuelle Darstellung über die Vorlage des Steuerelements definiert. Die Vorlage kann aus verschiedenen Quellen stammen, ist meist jedoch von Designstilen abgeleitet. Vorlagen verfügen über eine dynamische Bindung. Die erforderliche Vorlage wird nicht an das jeweilige Steuerelement angefügt, bevor das Steuerelement für den Layoutvorgang bereit ist. Das Steuerelement ist so lange nicht für den Layoutvorgang bereit, bis es einer logischen Struktur zugeordnet wird, deren Stammebene über eine Verbindung zu einer Renderingoberfläche verfügt. Dieses Stammebenenelement initiiert das Rendering aller untergeordneten Elemente, die in der logischen Struktur definiert sind.
Die visuelle Struktur ist an diesem Prozess auch beteiligt. Elemente, die über die Vorlagen Teil der visuellen Struktur sind, werden ebenfalls nicht vollständig instanziiert, bevor sie verbunden sind.
Die Konsequenz dieses Verhaltens ist, dass bestimmte Vorgänge, die sich auf die fertigen visuellen Merkmale eines Elements beziehen, zusätzliche Schritte erfordern. Ein Beispiel hierfür ist, wenn Sie versuchen, die visuellen Merkmale einer Klasse abzurufen, die erstellt wurde, jedoch noch keiner Struktur zugeordnet wurde. Wenn Sie zum Beispiel Render für RenderTargetBitmap aufrufen möchten und es sich bei dem übergebenen visuellen Element nicht um ein Element handelt, das über eine Verbindung zu einer Struktur verfügt, erlangt das Element seine visuelle Vollständigkeit erst, nachdem zusätzliche Initialisierungsschritte durchgeführt wurden.
Verwenden von BeginInit und EndInit zum Initialisieren des Elements
Verschiedene Klassen in WPF implementieren die ISupportInitialize-Schnittstelle. Sie verwenden die Methoden BeginInit und EndInit der Schnittstelle, um einen Bereich im Code anzugeben, der Initialisierungsschritte enthält (zum Beispiel das Festlegen von Eigenschaftswerten für das Rendering). Nachdem in der Sequenz EndInit aufgerufen wurde, kann das Layoutsystem das Element verarbeiten und mit der Suche nach einem impliziten Stil beginnen.
Wenn es sich bei dem Element, für das Sie Eigenschaften festlegen, um eine abgeleitete Klasse vom Typ FrameworkElement oder FrameworkContentElement handelt, können Sie die Klassenversionen von BeginInit und EndInit aufrufen, anstatt eine Umwandlung in ISupportInitialize durchzuführen.
Beispielcode
Beim folgenden Beispiel handelt es sich um Beispielcode für eine Konsolenanwendung, die das APIs-Rendering und XamlReader.Load(Stream) einer losen XAML-Datei verwendet, um die richtige Positionierung von BeginInit und EndInit in Bezug auf andere API-Aufrufe anzuzeigen, die eine Anpassung von Rendering-bezogenen Eigenschaften vornehmen.
Das Beispiel zeigt nur die Hauptfunktion. Die Funktionen Rasterize und Save (nicht gezeigt) sind Hilfsfunktionen, die für die Bildverarbeitung und Eingabe/Ausgabe verwendet werden.
<STAThread>
Shared Sub Main(ByVal args() As String)
Dim e As UIElement
Dim _file As String = Directory.GetCurrentDirectory() & "\starting.xaml"
Using stream As Stream = File.Open(_file, FileMode.Open)
' loading files from current directory, project settings take care of copying the file
Dim pc As New ParserContext()
pc.BaseUri = New Uri(_file, UriKind.Absolute)
e = CType(XamlReader.Load(stream, pc), UIElement)
End Using
Dim paperSize As New Size(8.5 * 96, 11 * 96)
e.Measure(paperSize)
e.Arrange(New Rect(paperSize))
e.UpdateLayout()
'
' * Render effect at normal dpi, indicator is the original RED rectangle
'
Dim image1 As RenderTargetBitmap = Rasterize(e, paperSize.Width, paperSize.Height, 96, 96)
Save(image1, "render1.png")
Dim b As New Button()
b.BeginInit()
b.Background = Brushes.Blue
b.Height = 200
b.Width = b.Height
b.EndInit()
b.Measure(paperSize)
b.Arrange(New Rect(paperSize))
b.UpdateLayout()
' now render the altered version, with the element built up and initialized
Dim image2 As RenderTargetBitmap = Rasterize(b, paperSize.Width, paperSize.Height, 96, 96)
Save(image2, "render2.png")
End Sub
[STAThread]
static void Main(string[] args)
{
UIElement e;
string file = Directory.GetCurrentDirectory() + "\\starting.xaml";
using (Stream stream = File.Open(file, FileMode.Open))
{
// loading files from current directory, project settings take care of copying the file
ParserContext pc = new ParserContext();
pc.BaseUri = new Uri(file, UriKind.Absolute);
e = (UIElement)XamlReader.Load(stream, pc);
}
Size paperSize = new Size(8.5 * 96, 11 * 96);
e.Measure(paperSize);
e.Arrange(new Rect(paperSize));
e.UpdateLayout();
/*
* Render effect at normal dpi, indicator is the original RED rectangle
*/
RenderTargetBitmap image1 = Rasterize(e, paperSize.Width, paperSize.Height, 96, 96);
Save(image1, "render1.png");
Button b = new Button();
b.BeginInit();
b.Background = Brushes.Blue;
b.Width = b.Height = 200;
b.EndInit();
b.Measure(paperSize);
b.Arrange(new Rect(paperSize));
b.UpdateLayout();
// now render the altered version, with the element built up and initialized
RenderTargetBitmap image2 = Rasterize(b, paperSize.Width, paperSize.Height, 96, 96);
Save(image2, "render2.png");
}