Initialisierung für Objektelemente außerhalb einer ObjektstrukturInitialization for Object Elements Not in an Object Tree

Einige Aspekte der Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)-Initialisierung werden für Prozesse zurückgestellt, die sich in der Regel darauf verlassen, dass das Element entweder mit einer logischen Struktur oder einer visuellen Struktur verbunden wird.Some aspects of Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) initialization are deferred to processes that typically rely on that element being connected to either the logical tree or visual tree. Dieses Thema beschreibt die Schritte, die möglicherweise erforderlich sind, um ein Element zu initialisieren, das nicht mit einer dieser Strukturen verbunden ist.This topic describes the steps that may be necessary in order to initialize an element that is not connected to either tree.

Elemente und die logische StrukturElements and the Logical Tree

Beim Erstellen einer Instanz einer Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)-Klasse im Code sollten Sie bedenken, dass verschiedene Aspekte der Objektinitialisierung für eine Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)-Klasse absichtlich keinen Teil des Codes sind, der beim Aufrufen des Klassenkonstruktors ausgeführt wird.When you create an instance of a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) class in code, you should be aware that several aspects of object initialization for a Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) class are deliberately not a part of the code that is executed when calling the class constructor. Insbesondere für eine Steuerelementklasse ist der Großteil der visuellen Darstellung dieses Steuerelements nicht vom Konstruktor definiert.Particularly for a control class, most of the visual representation of that control is not defined by the constructor. Stattdessen wird die visuelle Darstellung durch die Vorlage des Steuerelements definiert.Instead, the visual representation is defined by the control's template. Die Vorlage stammt möglicherweise aus einer Vielzahl von Quellen, ganz oft wird die Vorlage jedoch aus Designstilen.The template potentially comes from a variety of sources, but most often the template is obtained from theme styles. Vorlagen sind eine effektive späte Bindung; die erforderliche Vorlage wird dem fraglichen Steuerelement nicht angefügt, solange das Steuerelement nicht für Layout bereit ist.Templates are effectively late-binding; the necessary template is not attached to the control in question until the control is ready for layout. Das Steuerelement ist so lange nicht für Layout bereit, bis es einer logischen Struktur angefügt wird, die eine Verbindung mit einer Renderingoberfläche auf der Stammebene eingeht.And the control is not ready for layout until it is attached to a logical tree that connects to a rendering surface at the root. Es ist das Rootebenenelement, dass das Rendering aller untergeordneten Elemente initiiert, so wie in der logischen Struktur definiert.It is that root-level element that initiates the rendering of all of its child elements as defined in the logical tree.

Die visuelle Struktur beteiligt sich auch an diesem Prozess.The visual tree also participates in this process. Elemente, die Teil der visuellen Struktur durch die Vorlagen sind, werden ebenfalls nicht vollständig instanziiert, bis sie verbunden sind.Elements that are part of the visual tree through the templates are also not fully instantiated until connected.

Die Folgen dieses Verhaltens sind, dass bestimmte Vorgänge, die auf den fertigen visuellen Merkmalen eines Elements basieren, zusätzliche Schritte erfordern.The consequences of this behavior are that certain operations that rely on the completed visual characteristics of an element require additional steps. Ein Beispiel ist, wenn Sie versuchen, visuelle Merkmale einer Klasse abzurufen, die erstellt aber noch nicht einer Struktur angefügt wurde.An example is if you are attempting to get the visual characteristics of a class that was constructed but not yet attached to a tree. Wenn Sie z. b. Render auf einem RenderTargetBitmap aufzurufen haben und das visuelle Element, das Sie übergeben, ein Element ist, das nicht mit einer Struktur verbunden ist, ist dieses Element erst visuell abgeschlossen, wenn weitere Initialisierungs Schritte ausgeführt wurden.For instance, if you want to call Render on a RenderTargetBitmap and the visual you are passing is an element not connected to a tree, that element is not visually complete until additional initialization steps are completed.

Verwenden von BeginInit und EndInit zum Initialisieren des ElementsUsing BeginInit and EndInit to Initialize the Element

Verschiedene Klassen in WPFWPF die ISupportInitialize-Schnittstelle implementieren.Various classes in WPFWPF implement the ISupportInitialize interface. Verwenden Sie die Methoden BeginInit und EndInit der-Schnittstelle, um einen Bereich im Code anzugeben, der Initialisierungs Schritte enthält (z. b. das Festlegen von Eigenschafts Werten, die sich auf das Rendering auswirken).You use the BeginInit and EndInit methods of the interface to denote a region in your code that contains initialization steps (such as setting property values that affect rendering). Nachdem EndInit in der Sequenz aufgerufen wurde, kann das Layoutsystem das Element verarbeiten und mit der Suche nach einem impliziten Stil beginnen.After EndInit is called in the sequence, the layout system can process the element and start looking for an implicit style.

Wenn das Element, für das Sie Eigenschaften festlegen, eine FrameworkElement oder FrameworkContentElement abgeleitete Klasse ist, können Sie die Klassen Versionen von BeginInit und EndInit anstelle von Umwandlungen in ISupportInitializeaufzurufen.If the element you are setting properties on is a FrameworkElement or FrameworkContentElement derived class, then you can call the class versions of BeginInit and EndInit rather than casting to ISupportInitialize.

BeispielcodeSample Code

Das folgende Beispiel zeigt Beispielcode für eine Konsolenanwendung, die Renderingerweiterungen und XamlReader.Load(Stream) einer losen XAMLXAML Datei verwendet, um die ordnungsgemäße Platzierung BeginInit und EndInit von anderen API-aufrufen zu veranschaulichen, die Eigenschaften anpassen, die sich auf das Rendering auswirken.The following example is sample code for a console application that uses rendering APIs and XamlReader.Load(Stream) of a loose XAMLXAML file to illustrate the proper placement of BeginInit and EndInit around other API calls that adjust properties that affect rendering.

Das Beispiel veranschaulicht nur die Hauptfunktion.The example illustrates the main function only. Die Funktionen Rasterize und Save (nicht dargestellt) sind Hilfsfunktionen, die die Verarbeitung und E/A erledigen.The functions Rasterize and Save (not shown) are utility functions that take care of image processing and IO.

[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");
}
        <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

Siehe auchSee also