2013-12-11 45 views
16

XAML (veya BAML) yükleniyor ve kök nesneyi (örneğin, Window) almak arasında dahili olarak ne olur?XAML, çalışma zamanında nasıl yorumlanır ve yürütülür?

Aklımda ilk ortaya çıkan şey, Reflecton'un nesne oluşturmak, özelliklerini ayarlamak ve benzeri işlemlerde kullanılmasıdır. Ama belki yanılıyor muyum?

Belki de birisi XAML/BAML'nin çalışma zamanında nasıl ayrıştırıldığını ve çalıştırılacağını açıklayabilir veya açıklama ile iyi bir makalenin bağlantısını nasıl verebilir?

<Button Margin="10">OK</Button> 

Yani, çözümleyici, Marj özelliği ayarlı olması gerektiğini, bir Düğme nesnesi oluşturulması gerekir görür:

en kısa örneğini ele alalım, biraz daha net sorumu yapmak için 10 ve içeriği "OK" olarak ayarlanmalıdır. Bu nasıl yapılır? Yansıma (artı TypeConverters, vb) kullanarak?

cevap

25

.xaml.cs dosyalarında, derlenmiş XAML dosyalarınızı destekleyen sınıfların partial sınıfları olarak işaretlendiğini görebilirsiniz. Bir XAML derleme görevi, arkadaki kodda varsayılan yapıcı tarafından çağrılan IComponentConnector.InitializeComponent() yönteminin bir uygulamasını içeren başka bir kısmi sınıf bölümüyle ikinci bir .cs dosyası oluşturur. Bu yöntem temelde XAML (aslında bu noktada BAML formundadır) aracılığıyla çalışır ve XAML kaynağından yeni bir nesne oluşturmanın aksine, yeni oluşturulan nesneyi "düzeltmek" için kullanır. Bir nesneyi yüklemek veya ayrıştırmak için XamlReader kullanmak vardı. Bu nedenle, yeni derlenmiş bir XAML nesnesini (ör., UserControl) başlattığınızda, yapıcıda InitializeComponent() çağrısının önündeki herhangi bir kodun yürütülmesi gerekir. Ardından, XAML dosyasında ayarlanan tüm özellikler ve olay işleyicileri, çağrı sırasında InitializeComponent() numaralı telefona işlenecek ve sonra kurucunun devam etmesi sağlanacaktır. Bu, XAML dosyasının işlenmesinden önce veya sonra belirli özelliklerin ayarlanmasını sağlamak isteyebileceğinizden, bilmek faydalı olabilir.

XAML'nin nasıl ayrıştırıldığına ilişkin olarak, temel olarak, System.Xaml numaralı hizmetlerdeki hizmetler tarafından gerçekleştirilen özellik atamaları, nesne bildirimleri vb. Temsil eden bir XAML düğümleri akışı olarak okunur. Bu düğüm akışı, bir BAML akışından, bir XML belgesinden (örneğin, bir gevşek .xaml dosya), başka bir nesne örneğinden vb. Oluşturulmuş olan ortak bir nesne modeline dayanır. BAML, XML tabanlı formattan daha kompakttır. , genellikle ayrıştırmak için daha hızlıdır.


Zeyilname: eklemiş örnekte, sen ayrıştırıcı bir Button nesne oluşturulması gerekir ve Margin seti olduğunu nasıl gördüğünü sorun. Kısa cevap: buna bağlı. Özellikle, XAML akışını okumak için kullanılan şema içeriğine bağlıdır.

XAML ayrıştırıcı en az iki uygulama var olan, kendi tür sistemi kullanır:

  1. standart CLR tipi sistem yansıtma ve System.ComponentModel göre;
  2. Bağımlılık özellikleri ve yönlendirilen olaylar için özel destek ekleyerek # 1'i genişleten WPF tipi bir sistem.

Bu, XAML Dil Spec benim hatırlama dayanır yaklaşık ne olur:

  1. XAML çözümleyici Button tipi için StartObject düğümü karşılaştığında hangi (standart WPF ad eşleme için) System.Windows.Controls.Button'a gider. Bu, ayrıştırıcıya varsayılan yapıcısını yansıtma yoluyla çağırarak, Button nesnesinin bir örneğini oluşturmak için gereksinim duyduğunu bildirir.
  2. Akıştaki bir sonraki düğüm, Margin üye adına sahip bir StartMember düğümüdür. WPF şeması bağlamının tip modeli bunu Margin bağımlılık özelliğine çözecektir.
  3. Bir ayrıştırıcıya "10" (bir dize) değeri ayarlamasını bildiren bir Value node gelir. Ayrıştırıcı, Thickness özellik türünün dize değeri ile uyumsuz olduğunu görür. Dize dönüştürmek için kullanılabilecek Margin özelliğinde [ValueSerializer] özniteliğinin olup olmadığını görmek için tür sistemine danışır; böyle bir özellik yoktur. Bir [TypeConverter] özniteliği için özelliği denetler; yine, hiçbiri bulamaz. Thickness türünde bir [TypeConverter] özniteliği arar ve bir dize değerini Thickness'a dönüştürmek için bir ThicknessConverter kullanmasını bildiren birini bulur. Öyle yapar. Margin bağımlılık özelliği olduğundan, özellik değerini ayarlamak için SetValue() API'sini kullanır; Bir CLR özelliği olsaydı, yansıma veya PropertyDescriptor kullanırdı.
  4. Bir EndMember düğümü, ayrıştırıcının özellik atamasını sonlandırmasını söyler. Ayrıştırıcı, "OK" numaralı içeriğe sahip bir Value düğümüyle karşılaşır. Ayrıştırıcı, karmaşık bir nesne oluşturduğunu bildiğinden, içerik tüm nesneyi temsil edemez. [ContentProperty] özniteliğine Button ve onun süper yönleri için bakar; ContentControl'dan birini bulur ve bu değer, Content özelliğinin ayarlanması için kullanılması gerektiğini belirtir (ilgili bağımlılık özelliğine çözülür). Content bir object, bu nedenle string değerini doğrudan (SetValue() kullanarak) atar.
  5. Bir sonraki düğüm, ayrıştırıcıya Button nesnesini işlemeyi tamamladığını bildiren EndObject.

Öğeleri basitleştirmek için "ayrıştırıcı" terimini kullandım. Doğrusu, hiçbiri ayrıştırma aşamasında olmaz (bir "ayrıştırma" aşaması bile mevcutsa). "Ayrıştırma" aşaması olarak düşünebileceğiniz şey, sadece bir XAML düğümleri akışıdır. Beyan edilen nesnenin/nesnelerin yaratılması ve/veya popülasyonu, bu akışı bir XamlObjectWriter içine beslemek suretiyle gerçekleşir, bu sadece XAML düğümlerini bir nesneye (bir XML belgesinin veya bir BAML akışının aksine) yazan XamlWriter'un uygulanmasıdır.

  1. XamlReader XAML düğümlerinin akışı içine bir şey dönüştüren: Yüksek seviyede, oluyor sadece iki şey vardır.
  2. XamlWriter, bir XAML düğümleri akışını bir şeye dönüştürür. Bir compled XAML kaynak durumunda

, bir derleme zamanı inşa görev boruları bir BamlWriter içine XamlXmlReader çıkış XAML "derlemek" için.Çalışma zamanında, BamlReader girişi, kök nesneyi oluşturmak veya "düzeltmek" için XamlObjectWriter'a aktarılır.

Tüm bunları anladıktan sonra, yalnızca UI'leri oluşturmak için bir dilin aksine XAML'yi güçlü bir serileştirme ve kalıcılık biçimi olarak tanımaya başlayabilirsiniz.

+0

Mike, cevabınız için teşekkür ederim. Ek ihtiyaç duyduğum şey. Bu nedenle, WPF motoru tarafından bir nesne ağacı oluşturmak, mikro örneğimizde, bir Button nesnesinin oluşturulması, hangi TypeConverter'ın kullanılacağını, bir TypeConverter inşasını, Marjın bir bağımlılık özelliği olduğunu öğrenmesini, vb. – WpfNewbie

+1

Evet, XAML tipi sistemde iyi bir yansıma var. –

+0

Harika cevap! – nawfal

İlgili konular