Aracılığıyla paylaş


Nesne Ağacında Olmayan Nesne Öğeleri için Başlatma

Windows Presentation Foundation (WPF) başlatmasının bazı yönleri, genellikle mantıksal ağaca veya görsel ağaca bağlı olan o öğeye ihtiyaç duyan işlemlere ertelenmektedir. Bu konuda, herhangi bir ağaca bağlı olmayan bir öğeyi başlatmak için gerekli olabilecek adımlar açıklanmaktadır.

Öğeler ve Mantıksal Ağaç

Kodda bir Windows Presentation Foundation (WPF) sınıfının örneğini oluşturduğunuzda, Windows Presentation Foundation (WPF) sınıfı için nesne başlatmanın çeşitli yönlerinin, sınıf oluşturucusu çağrılırken yürütülen kodun bir parçası olmadığını bilmelisiniz. Özellikle bir denetim sınıfı için, bu denetimin görsel gösteriminin çoğu oluşturucu tarafından tanımlanmaz. Bunun yerine, görsel gösterim denetimin şablonu tarafından tanımlanır. Şablon büyük olasılıkla çeşitli kaynaklardan gelir, ancak çoğu zaman şablon tema stillerinden elde edilir. Şablonlar fiilen geç bağlanmaktadır; gerekli şablon, ilgili denetime, denetim düzen için hazır olana kadar eklenmez. Denetim, kökteki işleme yüzeyine bağlanan mantıksal bir ağaca bağlanana kadar düzen için hazır değildir. Mantıksal ağaçta tanımlandığı gibi tüm alt öğelerinin işlenmesini başlatan kök düzeyi öğedir.

Görsel ağaç da bu işleme katılır. Şablonlar aracılığıyla görsel ağacın bir parçası olan öğeler, bağlantı sağlanana kadar tamamen örneklenmez.

Bu davranışın sonuçları, bir öğenin tamamlanmış görsel özelliklerine dayanan belirli işlemlerin ek adımlar gerektirmesidir. Örneğin, oluşturulmuş ancak henüz bir ağaca bağlı olmayan bir sınıfın görsel özelliklerini almaya çalışıyorsunuzdur. Örneğin, Render üzerinde bir RenderTargetBitmap çağırmak istiyorsanız ve aktardığınız görsel bir ağaçla ilişkili olmayan bir öğeyse, bu öğe ek başlatma adımları tamamlanana kadar görsel olarak tamamlanmaz.

Öğesini Başlatmak için BeginInit ve EndInit Kullanma

WPF'deki çeşitli sınıflar ISupportInitialize arabirimini uygular. Arabirimin BeginInit ve EndInit yöntemlerini kullanarak kodunuzda başlatma adımları (işlemeyi etkileyen özellik değerlerini ayarlama gibi) içeren bir bölgeyi belirtirsiniz. EndInit sırayla çağrıldıktan sonra düzen sistemi öğeyi işleyebilir ve örtük bir stil aramaya başlayabilir.

Özelliklerini ayarladığınız öğe FrameworkElement veya türetilmiş FrameworkContentElement bir sınıfsa, BeginInit'e atama yerine EndInit ve ISupportInitialize sınıf sürümlerini çağırabilirsiniz.

Örnek Kod

Aşağıdaki örnek, işleme API'lerini kullanan bir konsol uygulamasına ait örnek kodudur ve gevşek bir XAML dosyasının XamlReader.Load(Stream)'ını kullanarak, BeginInit ve EndInit'nin, işleme etkisi yaratan özellikleri ayarlayan diğer API çağrıları etrafındaki doğru yerleşimini göstermektedir.

Örnekte yalnızca ana işlev gösterilmektedir. Rasterize ve Save işlevleri (gösterilmez) görüntü işleme ve GÇ ile ilgilenen yardımcı program işlevleridir.

[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

Ayrıca bakınız