Demo etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Demo etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Pazartesi, Haziran 02, 2008

WPF - Text & Flow Document

Metinler hazırladığımız uygulamaların vazgeçilmezledir. Windows Presentation Foundation ile metin işlemlerini kullanırken bir çok özelliği kolaylıkla kullanmamıza olanak tanınmaktadır. WPF, metin görüntülenmesine olanak tanınan her yerde yazılarımızı görüntülememize olanak tanımaktadır. Basit metin formatlarından çok daha karışık formatlara ve istediğimiz biçimde stillendirdiğimiz metinlere kadar çok geniş bir yelpaze WPF ile sunulmaktadır. Metinleri kullanırken yalnızca yazılarla kalmayıp kullanıcı kontrollerini, grafiklerini de kullanabilmemiz mümkündür. Metin işlemlerinde en göze çarpan ve yapılması istenen bir diğer özellik ise tip kontrolleridir. WPF‘ te bu işlemler içinde Typography sınıfı kullanılmaktadır. Ayrıca oluşturduğumuz olan metinlerin uygulamamızda daha derli toplu görülebilmesi için Flow Document ( akan belgeler ) ve Fixed Document ( değişmez belgeler ) sınıfları kullanılmaktadır. Bu sınıfların kontrollerini kullandığımız zaman ise bizlere birçok kontrolü içinde barındıran kontrol sunulmaktadır. Biz bu makalemize süresinde yukarıda bahsettiğimiz bütün özellikleri incelemeye çalışacağız. İlk olarak incelemeye başlamadan önce Flow Document kullanılan birkaç uygulamadan örnek olacak.

Türkiye’ de ve bütün dünyada Windows Presentation Foundation tanıtımları yapılırken gösterilen ortak bir uygulama vardı. Demoda bir gazetenin internete başlanmadan videoları, resimleri ve içerikleri ile birlikte bilgisayarda kullanılmasına olanak tanıyan bir örnekti. Gösterilen demo New York Times Reader ‘dır. Uygulamada, yazılar belirli ölçülerde büyültülüp küçültülürken sayfalamalar ona göre otomatik olarak şekillendiriliyor, düzenli olarak güncelleme alabiliyor ve hem hızlı hem de görsel olarak son kullanıcının hoşuna gidecek animasyonlar sunuyordu. Kısacası geliştiriciler ve kullanıcılar bu uygulamayı fazlasıyla beğenmekteydi. Şimdi bu uygulama ve bu uygulama esas alınarak hazırlanan başka bir uygulamanın ekran görüntülerini aşağıda göreceksiniz. Bu uygulamaların ortak yanları;

Windows Presentation Foundation ile yapılmış olmaları,
Flow Document kontrolünün kullanılmış olması,
İçeriklerinin web servisler ile otomatik olarak çekiliyor olması,
Arama için gerekli olan sorgularında LinQ To SQL kullanmaları,
Sayfa geçişlerinde ve arama işlemleri sonuçlarında animasyon kullanılması,
biçiminde sıralayabilmemiz mümkündür.


New York Times Reader


MSDN Libary

Yukarıda ekran görüntülerini gördüğünüz uygulamaların en belirgin özellikleri içeriklerinden bulunan metinlerin uygulamanın boyutuna göre kendisini otomatik olarak şekillendirmesidir.

Artık temel olarak metin ve flow document ile neler yapabileceğimize göz attığımıza göre bizlerde bu tür uygulamalar geliştirmek istediğimizde kullanabileceğimiz metin özelliklerini incelemeye başlayabiliriz.

Yazı Tipi ve Metin Stilleri

Metin ile ilgili işlemler ile uğraştığımızda bir çok aşamayı başarılı bir biçimde yapabilmemiz gerekmektedir. Fakat WPF ile sağlanan kolaylıklar ve bünyesinde barındırdığı bir çok yazı tipi stilleri sayesinde daha kolaylıkla yapabilmemiz mümkündür. Metin uygulamalarında altı çizili olması, kalın olması, eğik olması, farklı yazı tiplerinin kullanılabilmesi, boyutlarının kolaylıkla değiştirilebilmesi ve işletim sistemlerinin temalarından doğan sorunların oluşmaması gibi bir çok faktörü düşünerek hareket ederiz. WPF ile ise bahsettiğimiz bir çok faktörü HTML ile kod yazarken yaşadığımız kolaylık ile uygulayabiliyoruz.

Yaygın Metin Özellikleri

WPF ile hazırlamış olduğumuz uygulamalarda metinleri belirlediğimiz zaman TextElement sınıfını çağırmamız gerekmektedir. TextElement sınıfına dahil edilmiş birçok özelliği kullanarak en yaygın olarak kullanılan metin işlemlerini yapabilmemiz mümkündür. Şimdi bu sınıfı buton kontrolünün içerisinde nasıl kullanabileceğimizi basit bir örnek ile inceleyelim.

XAML Kod
<Button TextElement.FontFamily="Parchment" TextElement.FontSize="80" Height="96" VerticalAlignment="Top">
    Turhal Temizer
</Button>
<Button FontFamily="Parchment" FontSize="80" Height="96" VerticalAlignment="Bottom">
    Duygu Çaglar
</Button>

XAML koddan dikkat edeceğiniz üzere TextElement sınıfı ile metin özelliklerine belirleyebilirken aynı zamanda direk yapmak istediğimiz metinsel değişikleri belirterek de yapabilmemiz mümkündür. İkisi arasında bir fark yoktur ve özellikler penceresinde yaptığımız işlemlerin sonucunun sorunsuz olduğunu görebiliriz.



Butonumuzun görüntüsünün nasıl gözüktüğüne görmek gerekirse,



iki butonda da belirttiğimiz yazı tipi ve boyutu sorunsuz bir biçimde uygulanmış olduğu görülür.
Text Element miraslaşarak oluşturulan özellikleri ve ne işe yaradıklarını aşağıdaki gibi listeleyebiliriz.



Özellik Kullanımı
FontFamily
Yazı biçimini belirler(Arial, Calibri, v.b.).
FontSize Yazıların boyutlarını belirler. (XAML‘ de kullanabileceğimiz boyut standartları: in, cm, px, pt ‘dir. Bu kısaltmalar ayrıntılı olarak inç, santimetre, piksel, nokta.) Eğer herhangi bir standart girilmezse varsayılan olarak piksel kabul edilir.
FontStretch Yazının gerginliğini belirler. Condensed, Normal ve Expanded değerlerini alır.
FontStyle Yazınını stilini belirler. Italic ve Normal değerlerini alır.
FontWeight Yazını genişliğini belirler. Normal, Bold ve Light değerlerini alır.
Foreground Yazının rengini belirler.

Daha öncede bahsettiğimiz gibi yukarıdaki özellikler kullanıcı kontrollerinde dahili olarak kullanılmaktadır ve TextElement sınıfının tekrardan çağırılmasına gerek yoktur.

Yazı ve Yazı Ailesi

Ortak kullanılan (FontFamily) yazı ailelerine ve tiplerine yer verilmiştir. Fakat FontFamily sınıfı kullanabileceklerimizden yalnızca biridir. WPF uygulamalarında sıklıkla kullanılan üç sınıfı ve kullanım biçimlerine ilişkin bilgiler aşağıdaki tablodadır.

Sınıf Kullanımı
FontFamily Yazı tiplerini isimleri ile temsil eder. Arial, Calibri, Times New Roman v.b. yazı tipleri kullanılabilmektedir.
GlypTypeface Diskimizdeki yazı tipini kullanır. C:\Windows\Fonts\timesbi.ttf gibi. Belirtilen yazı dosyasının içerisinden yazıya ilişkin stil, boyut ve diğer özellikleri bulunmaktadır. Yolunu verdiğimizde ise kalın, yassı ve stili Times New Roman dır.
Typeface FontFamily özelliklerini kullanır. GlypTypeface ile oluşturulan görüntülenmeler Typeface ile tekrardan görüntülenebilir.

Windows Presentation uygulamaları geliştirilirken sıklıkla kullanılan yazı ailesi FontFamily ‘dir. Diğer iki yazı ailesi ise genellikle tasarımcılar tarafından özelleştirilen yazı stillerinin kullanılması durumunda kullanılmaktadır. Fakat kullanım sıklığı ve kolaylığı göz önüne alındığında FontFamily ‘nin daha fazla kullanıldığı gözlenir.

Yazı Boyutu (FontSize)

Metin işlemlerinde kullanacak olduğumuz yazının boyutunu istediğimiz biçimde şekillendirmemize olanak tanır. Hangi değerler ile boyutlarını yaygın metin özellikleri başlığının altındaki tabloda incelemiştik. Şimdi bu değerleri nasıl kullanabileceğimize XAML kod ile göz atalım.

XAML kod
<StackPanel>
    <TextBlock FontSize="40 px" Text="30 piksel"/>
    <TextBlock FontSize="40 pt" Text="30 nokta"/>
    <TextBlock FontSize="1.3 cm" Text="1.3 santimetre"/>
    <TextBlock FontSize="0.4 in" Text="0.3 inç"/>
</StackPanel>



Gerginlik (Stretch)

Metin uygulamalarında yer alan yazıların ekrandaki gerginliklerini belirlenmesine yarar. Kullanılan değerler FontStretches sınıfından çekilir. Bu değerler: UltraCondensed, ExtraCondensed, Condensed, SemiCondensed, Normal, Medium, SemiExpanded, Expanded, ExtraExpanded ve UltraExpanded dir.

Sıklıkla kullanılan yazı stillerinde gerginlik değeri olarak normal kullanılmaktadır. Eğer ki diğer özellikler kullanılırsa yatay olarak harfler ve rakamlar birbirlerine çok yaklaşacak ve okuma güçlüğüne sebep olacaktır. Örnek olarak MS Office ‘de yer alan yazı tiplerinden Gill Sans MT‘ yi deneye bilirsiniz. Harflerin birbirine yakın olmasından dolayı okunma oldukça zordur.

Stil (Style)

FontStyle özelliği ile kullanılmaktadır. Kullanabileceğimiz değerleri: Normal, Italic ve Oblique ‘dir. Metinlerde farklı gösterilmesi düşünülen kelimelerde uygulanır. Arial yazı ailesi ile yazmış olduğumuz bir yazıya stilleri uyguladığımızda oluşan sonuç aşağıdaki gibidir.



Weight

FontWeight özelliği metin uygulamalarındaki yazılarımızın daha koyu bir biçimde görülmesini sağlar. FontWeight sınıfında birçok değer kullanılmaktadır. Bunlar: ExtraLight/UltraLight, Light, Normal/Regular, Medium, DemiBold / SemiBold, Bold, ExtraBold / UltraBold, Black / Heavy ve ExtraBlack / UltraHeavy dir.

TextElement sınıfında kullanılmakla birlikte paragraf veya blok yazı alanlarında da kullanılması mümkündür. Metin belgelerinde genellikle önem sarf eden veya başlık olacak olan yazılarda sıklıkla kullanılmaktadır.

Decoration (Süsleme)

Decoration özelliği yazıların altını veya üzerine düz bir çizgi çizmeye yaramaktadır. Genellikle TextBlock içerisinde kullanılmaktadır. Ayrıca TextDecorations ile düz siyah çizgi çizmenin dışında belirli ölçülerde özelleştirebildiğimiz düzlemlerde çizilebilmektedir. Örnek vermek gerekirse;

<TextBlock TextWrapping="Wrap" TextAlignment="Center" FontSize="18">
    <Span TextDecorations="Underline">Turhal Temizer, </Span>
    <Span TextDecorations="Baseline"> Duygu Çağlar, </Span>
    <Span TextDecorations="Strikethrough">Gövdesinde, </Span>
    <Span TextDecorations="Overline">Üzerinde, </Span>
    <Span TextDecorations="Underline, Baseline, Strikethrough, Overline">Hepsi</Span>
</TextBlock>
 

Şimdi ki örneğimizde ise standart siyah çizgini yerine mavi renkli kalın bir çizgiyi nasıl oluşturabileceğimize göz atacağız.

<TextBlock Margin="0,74,0,-74" FontSize="38" TextAlignment="Center">
    <Span>
        <Span.TextDecorations >
            <TextDecoration Location="Underline" PenOffset="4">
                <TextDecoration.Pen>
                    <Pen Brush="Blue" Thickness="1"/>
                </TextDecoration.Pen>
            </TextDecoration>
            <TextDecoration Location="Strikethrough">
                <TextDecoration.Pen>
                    <Pen Brush="LightGreen" Thickness="1"/>
                </TextDecoration.Pen>
            </TextDecoration>
        </Span.TextDecorations>
        Turhal Temizer
    </Span>
</TextBlock>



Windows Presentation Foundation da TextDecoration işlemlerini XAML kod yardımı ile ne kadar kolay yapabileceğimizi öğrenmiş olduk.

Text Wrapping & Hyphenation ( Metin aktarma ve Kesikli çizgi )

Son kullanıcılara sunulan uygulamalarda genellikle doldurmalı alanlar kullanıcılar tarafından uygulama alanının genişliğinden daha fazla yer kullanarak taşmasına sebep olmaktadır. Bu tür sorunları ortadan kaldırmak için kullanıcıya sunulan kontrolün genişliği tamamlandı ise bir alt satıra geçirilmesi için ufak ayarlamalar yapılırdı. WPF ‘de bu işlemleri iki biçimde yapabilmemiz mümkündür. Bunlardan birincisi TextWrapping ‘tir.

TextWrapping özelliği yazı yazdırılan satır dolmuş ise bir alt satıra geçmesine olanak tanımaktadır. Örnekler ile bu özelliği incelemek çok daha yararlı olacaktır.

TextWrapping özelliğini kullanmadan,

<TextBlock TextWrapping="NoWrap" Text="Turhal Temizer, Istatistik ve Bilgisayar Bilimleri, Karadeniz Teknik Universitesi"/>



TextWrapping özelliğini kullanarak,

<TextBlock TextWrapping="Wrap" Text="Turhal Temizer, Istatistik ve Bilgisayar Bilimleri, Karadeniz Teknik Universitesi"/>



TextWrapping özelliğinin üçüncü değeri ise WrapWithOverflow ‘dur. Bu değer daha çok geniş boyutlu uygulamalarda Wrap ‘a göre daha iyi performans vermektedir.

TextWrapping özelliği ile birlikte kullanabileceğimiz Hyphenation özelliği kelimeleri satıra sığabilecek kadar uzatır ve sığmayan kısmına kesikli çizgi “-” koyarak bir alt satırda kaldığı yerden devam etmektedir. Örnek olarak göstermek gerekirse,

<TextBlock TextWrapping="Wrap" IsHyphenationEnabled="True" Text="TextWrapping özelliği kullanabileceğimiz Hyphenation ..."/>



Text Alignment ( Metin Hizalaması )

Yazıların sağa sola, ortaya veya her iki yana yaslı olarak yazılmasına olanak tanınmaktadır. Bu işlemin gerçekleşebilmesi için TextAlignment özelliğine right, left, justify ve center özelliklerinden herhangi birinin girilmesi yeterlidir. Özelliğin uygulamalarını sıklıkla MS Office ‘te görebiliriz. İlk açılan belge sağa yaslı olarak yazmaya başlarken biz onu sayfanın istediğimiz yerinde başlamasına olanak sağlarız.

Metin ve Kullanıcı Arayüzü

WPF uygulamalarında tasarım mimarisi kullanıcı kontrollerinin kullanımı üzerine kurulmuştur. Hiyerarşinin gerçekleşmesinden kullanılan sınıflardan biri Glyph sınıfıdır. System.Windows.Forms.Design.Behavior isim alanından miraslaşarak oluşturulmuştur. Kullanılan kontrollerin form üzerinde gösterdiği özelliklere göre düzenlenmiştir. Hiyerarşinin en üst kademelerinden birinde yer alan Glyph sınıfı ile birlikte GlyphRunDrawing sınıfı kullanılmaktadır. System.Windows.Media isim alanından miraslaşmıştır. Kullanılan sınıfların modellenmesi ile metin işlemlerinde kullanabileceğimiz TextBlock ve FlowDocumentReader kullanıcı kontrolleri bizlere sunulmuştur. Şimdi sıklıkla kullanılan metin kontrollerini incelemeye çalışalım.

TextBlock

TextBlock kontrolü genellikle basit metinlerin görüntülenmesinde kullanılmaktadır. Birkaç kelimelik cümlelerin yazımında yazı stillerinin özelleştirilmesi gibi özellikleri kullanabilmemiz mümkündür. Basit olarak TextBlock kontrolünün nasıl kullanacağını gösterirsek,

<TextBlock Text="Turhal Temizer"/>

XAML kod bloğu biçimindedir. TextBlock kontrolünün form üzerinde nerede duracağı FrameworkElement yardımı ile belirtilebilmektedir. Ayrıca WPF formda Grid alanı yerine StackPanel kullanırsak ta kullanmış olduğumuz yazılar ve kontroller biz aksini belirtmediğimiz sürece alt alta dizilecektir.

TextBlock ‘ta çoklu satırda kullanılabilmektedir. Fakat kullanımı için doğru karakterleri kullanabilmesi gerekmektedir. .Net ‘te Environment.NewLine özellikleri yardımı ile kullanılması mümkündür. Karakterler kullanılarak hazırlanmış TextBlock kontrol örneği aşağıdadır.

<TextBlock Text="Turhal&#x0a; Temizer" />

&#x0a; kullanıldığı taktirde bitiminden sonraki kelimenin bir alt satırdan başlamasını sağlamaktadır.

TextBlock kontrolleri kullanılırken yazı ailesi ve stillerde kullanılabilmektedir. Ayrıca içerik olarak belirttiğimiz metinleri <TextBlock> tagları arasında kullanabilmemiz mümkündür.

<TextBlock>Turhal Temizer</TextBlock>

Metinlerde öncelikli olarak göstermemiz gereken kelimeleri kalın olarak göstermek isteyebiliriz. Bunun için yapmamız gereken HTML kodda olduğu gibi Bold tagını kullanmak olacaktır (HTML ‘de bold tagı strong biçiminde kullanılmaktadır).

<TextBlock><Bold>Turhal Temizer</Bold></TextBlock>



Metin modellerinde kullanabileceğimiz stilleri yukarıda ayrıntılı bir biçimde açıklamıştık. Bahsettiğimiz özelliklerin hepsi TextBlock modeli içerisinde kullanılabilmektedir.

Label ve AccessText

Label, etiket olarak göstermek istediğimiz metinlerde sıklıkla kullanılmaktadır. Özellikle Windows Form ‘larda kullanıcı tarafından değiştirilmesini istemediğimiz metinleri kullanırken en sık tercih edilen kontroldü. Aynı şekilde bu kontrol TextBlock ile birlikte WPF form uygulamalarında da yerini almıştır. Fakat en belirgin farkı istediğimiz bir harfi klavyeden alt karakterine bastığımızda altı çizili olarak gösterebilmemizdir. Bu kullanım şeklini Windows Form ile yapmak istediğimizde kullandığımız karakterlerin hepsini ekranda göstermektedir. Altı çizili olarak gösterebilmek için istediğimiz bir harfin önüne “-” karakterini koymamız yeterli olacaktır.

<Label FontSize="20" Content="D_uygu Çağlar Label"/>

Label gibi kullanacağımız bir diğer kontrolde AccessText ‘tir. Bu kontrolde label gibi çalışmakla birlikte ilk kullanışta göze çarpan ilk farkı WPF formun en köşe noktasından başlıyor oluşudur. Label kontrolü en köşe noktadan bir boşluk mesafede metinleri göstermektedir. Kullanımda olmasa da metinleri girerken XAML kod tarafında ufak bir değişiklik ile metinleri girmek gerekmektedir. Label kontrolünden metinleri Content özelliği ile girerken AccessText kontrolü ile Text özelliği ile girmemiz gerekmektedir.

<AccessText Text="T_urhal Temizer AccessText"/>

İki kontrolün klavyeden alt karakterine basılması sonucunda aldığı ekran görüntüsü aşağıdaki gibi olacaktır.



FlowDocument

Flow Document kontrolü WPF ile gelen en büyük yeniliklerden biridir. Biraz önce bahsettiğimiz metin girme kontrolleri temel olarak uzun olmayan metinlerin girilmesinde kullanılmaktadır. Fakat paragraflarca metinlerin uygulamamıza eklenmesini istediğimizde o kontroller yeteri verimi verememektedir. Bu durumda bizlerin yapması gereken satır sonlarına geldiğinde düzenli olarak bir alt satıra geç, kullanıcı yazıyı büyütmek ve küçültmek istediğinde olabilmesi için kontroller yaz ve bunun gibi daha birçok işlemi yapmamız gerekmekteydi. Bunun yerine FlowDocument kontrolü kullanarak daha uygulamanın temellerinden karşılaşacağımız bir çok sorunu halletmiş oluruz.

Ayrıca ufak bir noktaya değinmek gerekirse, WPF form ile hazırlanmış uygulamalarda içerikleri gösterirken verilerin XML ile birlikte XPS (XML Paper Specifition) belgelerden çekildiğinden de bahsedilmektedir. Peki bu XPS doküman nedir? Şubat ayı itibari ile değiştirilemez doküman kategorisinde PDF ‘in yerine standart olarak kabul edilmiş bir belge türüdür. Kabul esnasında PDF ‘in kabul oranına nazaran çok daha yüksek bir oranla kabul edilmiştir. Belgeleri göstermek için internet tarayıcıları kullanmakta ve kullanımında kullanıcılara sunduğu işlemleri Flow Document ile gerçekleştirmektedir. Ayrıca Windows Vista ile hazırlanan belgeler XPS ile ve bu işletim sisteminin çıkması ile yaygınlaşmıştır. Microsoft ürünü olmakla birlikte diğer yazılım ve bilişim firmalarının da istediği bir belge standardıdır. Yalnızca lisans alım aşamasında Microsoft ‘un diğer firmalardan daha aktif davranmasından ötürü kendi bünyesine dahil etmedir.

XPS kullanımı esnasında API olarak System.IO.Packaging dönüşümünü kullanmaktadır. Daha ayrıntılı bilgi edinmek için ise http://www.microsoft.com/xps adresinden yararlanabilirsiniz.

FlowDocument oluştururken nasıl bir yol izlememiz gerektiğini örnek üzerinden anlatacağız. Bu işlem için <FlowDocument> kontrolü ve her paragraf için <Paragraph> üyesini kullanmamız gerekecektir.

<FlowDocument>
    <Paragraph FontSize="22">Text ile FlowDocument</Paragraph>
    <Paragraph FontSize="30">Flow Document</Paragraph>
    <Paragraph>Flow Document kontolü WPF ile …. </Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>..</Paragraph>
</FlowDocument>



Flow Document kontrolünü kullanarak aramadan, boyut arttırmaya kadar birçok işlemi bir arada yapmamıza olanak tanınmaktadır. Bu işlemler esnasında yazı stillerinden sağa ve sola dayalı olması yazılar büyüdüğünde formumuza göre otomatik olarak şekillendirilmesi gibi bir çok özelliği otomatik olarak yapmaktadır.



Flow Document ile kullanabileceğimiz blokları aşağıdaki gibi listeleye biliriz.

Blok Kullanımı
Paragraph XAML kod bloğundan FlowDocument kontrolüne metin eklememize olanak tanır. Eklemiş olduğumuz metinler basit metinler olmalıdır. Sınırsız sayıda kullanılabilir. Diğer bloklar ile iç içe kullanılabilmektedir.
Section Diğer bloklara çeşitli özellikler atanmasına yarar. Diğer bloklara belirginlik, arka plan, yazı rengi ve buna benzer özellikleri belirlenmesinde yarar. Taglar içerisinde yazı metin yazılamaz. Paragraph gibi metin bloklarını kapsayacak biçimde tanımlanabilir.
List Listeleme yapılması için sıralı numara, roma rakamı, kalın nokta gibi standart listeleme simgelerinin kullanılmasına olanak tanır.
Table Belgelerde tablo ile gösterime ihtiyaç duyulduğunda kullanılmaktadır.
BlockUIContainer FlowDocument içerisine son kullanıcılara hitaben resim, video, buton ve üç boyutlu nesneler eklenmesine olanak tanır.

FlowDocument içerisinde kullanılabilecek blokların hepsinin ortak biçimde kullanıldığı bir örnek hazırlayalım. Örneğimizde başlığın arka plan rengi, listeli metin, BlockUIContainer ve tablo bulunacaktır.



XAML kod
<Window x:Class="mak43.Window8"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Flow Document">
    <!--Kapsamlı örnek-->
    <FlowDocument>
        <Section LineHeight="2" Foreground="White" Background="Black">
            <Paragraph FontSize="22">Windows Presentation Foundation</Paragraph>
            <Paragraph FontSize="30">Kısa Açıklamalar</Paragraph>
        </Section>
    <Paragraph>WPF: Ön plana çıkan özellikleri</Paragraph>
        <List>
            <ListItem>
                <Paragraph>Uygulama ile uyumu</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Çözünürlüğe bağımlılığı</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Donanımlar ile uyumu</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Bildirimli programlama</Paragraph>
            </ListItem>
            <ListItem>
                <Paragraph>Özelleştirelebilir zengin kontroller</Paragraph>
            </ListItem>
        </List>
        <BlockUIContainer>
            <Viewbox>
                <StackPanel Orientation="Horizontal">
                    <Image Source="yapi.jpg" Margin="5"/>
                    <TextBlock VerticalAlignment="Center" Width="100" TextWrapping="Wrap">
                        .Net Framework 3.0 teknolojisinden bulunanlar.
                    </TextBlock>
                </StackPanel>
            </Viewbox>
        </BlockUIContainer>
        <Paragraph>
            .Net 3.0 yapısının tablo ile gösterimi
        </Paragraph>
        <Table CellSpacing="5" Padding="15" FontFamily="Segoe UI">
            <Table.Background>
                <LinearGradientBrush>
                    <GradientStop Color="Yellow" Offset="0"/>
                    <GradientStop Color="Orange" Offset="1"/>
                </LinearGradientBrush>
            </Table.Background>
            <!-- dört sütün oluşturuluyor: -->
            <Table.Columns>
            <TableColumn/>
            <TableColumn/>
            <TableColumn/>
            <TableColumn/>
            </Table.Columns>
            <!-- üç satır oluşturuluyor: -->
            <TableRowGroup>
                <TableRow>
                    <TableCell ColumnSpan= "4" TextAlignment="Center">
                        <Paragraph FontWeight="Bold">.NET Framework 3.0</Paragraph>
                    </TableCell>
                </TableRow>
                <TableRow>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center" LineHeight="70">
                        <Paragraph FontWeight="Bold">WPF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WCF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WF</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">WCS</Paragraph>
                    </TableCell>
                </TableRow>
                <TableRow>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">ADO.NET</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">ASP.NET
                        </Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">Windows Forms</Paragraph>
                    </TableCell>
                    <TableCell BorderBrush="Black" BorderThickness="2" Background="LightGray"
                        TextAlignment="Center">
                        <Paragraph FontWeight="Bold">...</Paragraph>
                    </TableCell>
                </TableRow>
            </TableRowGroup>
        </Table>
    </FlowDocument>
</Window>

Oluşturmuş olduğumuz uygulamanın boyutlarını değiştirdiğimiz taktirde uygulamamızın içerisinde yer alan metinlerde otomatik olarak şekillenecektir.

Span

Yazı stillerinde anlatırken altı çizili, kalın, yassı yazıların nasıl oluşturulacağından ayrıntılı bir biçimde değinmiştik. FlowDocument ile bu özellikler kullanılmak istendiğinde nasıl bir kullanım izleneceğine değinmeye çalışalım. Yazı ile anlatırken TextBlock kontrolü içerisinde nasıl kullanılacağından değinmeye çalışmıştık. Şimdi ise Paragraph bloğu arasında kullanacağız.

XAML Kod
<FlowDocument>
    <Paragraph>
        <Bold>Kalın</Bold>
        <Italic>Yassı</Italic>
        <Underline>Altında</Underline>
        <Hyperlink>Link</Hyperlink>
        <Span BaselineAlignment="Superscript">SıuperScript</Span>
        <Span BaselineAlignment="Subscript">SubScript</Span>
        <Span>
            <Span.TextDecorations>
                <TextDecoration Location="Strikethrough"/>
            </Span.TextDecorations>
            Strikethrought
        </Span>
    </Paragraph>
    <Paragraph>
    a
    <Bold>b
        <Italic>c
            <Underline>d
                <Hyperlink>e</Hyperlink>
            f</Underline>
        g</Italic>
    h
    </Bold>
    i
    </Paragraph>
</FlowDocument>



Sabit Bloklar

FlowDocument içerisine yerleştirmiş olduğumuz resim, videoların blok içerisinden nerede duracağını belirlememize olanak tanırlar. Sayfanın boyutunun değişmesi sonucunda oluşan görüntü bozukluklarını ortadan amaçlar. Ufak bir örnek ile nasıl kullanıldığına göz atalım.

<FlowDocument>
    <Paragraph FontSize="22">Windows Client</Paragraph>
    <Paragraph FontSize="30">WPF 'in Form Dünyasındaki Yeri</Paragraph>
    <Paragraph>
        <Figure Width="130">
            <BlockUIContainer>
                <Image Source="Turhal11.jpg"/>
            </BlockUIContainer>
        </Figure>
        Windows Presentation Foundation …
    </Paragraph>
    <Paragraph>Windows Form …</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>…</Paragraph>
    <Paragraph>
        Tabii bu yalnızca bir görüş. Bize doğrusunu zaman gösterecektir.
    </Paragraph>
    <Paragraph>
        <Bold>Turhal Temizer</Bold>
    </Paragraph>
</FlowDocument>



FlowDocument ‘e eklemiş olduğumuz resim varsayılan olarak formun ilk sütununun sağ köşesine eklenmiştir. Eğer biz resmin yerine değiştirmek istiyorsak yapmamız gereken VerticakAnchor ve HorizontalAnchor değerlerini belirlemek olacaktır. Örnekler ile sonuçlarına göz atalım.


HorizontalAnchor="ColumnLeft"


HorizontalAnchor="PageCenter"


HorizontalAnchor="PageRight" ve VerticalAnchor="PageTop"

FlowDocument Görüntüleme

FlowDocument ile açıklamaları anlatırken hazır kontrolün özelliklerini kısıtlayabileceğimizden de bahsetmiştik. Uygumalarımızın sağ alt köşesinde görüntüleme ile ilgili üç adet seçenek çıkmaktadır. Eğer geliştiriciler isterse bu üç kontrolden herhangi birini XAML kod bloğunda FlowDocument tagından önce yazarak varsayılan olarak uygulatabiliriz ve değiştirilmesini engelleyebiliriz.

Görüntüleme ile ilgili üç seçeneğin ne işe yaradığını aşağıdaki tabloda ayrıntılı bir biçimde öğrenebilirisiniz.

Görütüleme Görevi
FlowDocumentScrollViewer Belgelerin web sayfalarında veya MS Word ‘de olduğu gibi aşağı yukarı kaydırma çubuğu ile hareketlenebilmesini sağlar.
FlowDocumentPageViewer MS Word ‘de tam ekran belgeleri okurken gözlemlenen yapının aynısı çalıştırılır.
FlowDocumentReader Diğer iki görüntülemenin özelliklerinin birleşimi biçimindedir. Kullanıldığı taktirde diğerlerinden farklı olarak arama çubuğuda aktif olmaktadır.
Görüntülemeler sonucunda aşağıdaki gibi sonuç alırız.

<FlowDocumentScrollViewer>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentScrollViewer>



<FlowDocumentPageViewer>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentPageViewer>



<FlowDocumentReader>
    <FlowDocument>
        ………………………
    </FlowDocument>
</FlowDocumentReader>



Dipnot Ekleme

FlowDocument ile hazırlanmış uygulamalara göz attığımızda dipnot ekleme gibi seçeneklerin bulunduğunu gözlemleriz. WPF, FlowDocument kontrolünde kullanabilmemiz için dipnot ekleme ve önemlilik belirleme gibi kontrolleri bizlere sunmuştur. Özellikleri kullanabilmemiz için Annotation sınıfını kullanabilmemiz gerekmektedir. Bunun için ise System.Windows.Annotations isim alanının uygulaya eklenmesi gerekmektedir. Dipnot işlemleri esnasında aşağıdaki kontrolleri kullanabilmemiz mümkündür.

Komut Kullanımı
CreateTextStickyNoteCommand Eklenmesi durumunda seçili metnin üzerine gelindiğinde yazı olarak not eklenmesini sağlar.
CreateInkStickyNoteCommand Eklenmesi durumunda seçili metnin üzerine gelindiğinde çizerek not eklenmesini sağlar.
DeleteStickyNoteCommand Etiket olarak eklenen dipnotları silmeyi sağlar.
CreateHighlightCommand CreateHighlightCommand
ClearHighlightCommand Renklendirilmiş metnin temizlenmesini sağlar.

Yukarıdaki komutları kullanarak FlowDocument uygulamamızı özelleştirelim.

Uygulamamıza başlarken ilk yapacak olduğumuz işlem System.Windows.Annotations isim alanını eklemek olacaktır.



Daha sonrasında ise aşağıdaki XAML kodları ekliyoruz.

XAML kod
<Window x:Class="mak43.Window10"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:a="clr-namespace:System.Windows.Annotations;assembly=PresentationFramework"
    Title="Dipnot" Initialized="Window_Initialized" Closed="Window_Closed">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label>Dipnot Kontrolleri</Label>
            <Button Command="a:AnnotationService.CreateTextStickyNoteCommand"
                CommandTarget="{Binding ElementName=reader}">Yazılı Not</Button>
            <Button Command="a:AnnotationService.CreateInkStickyNoteCommand"
                CommandTarget="{Binding ElementName=reader}">Çizimli Not</Button>
            <Button Command="a:AnnotationService.DeleteStickyNotesCommand"
                CommandTarget="{Binding ElementName=reader}">Not sil</Button>
            <Button Command="a:AnnotationService.CreateHighlightCommand"
                CommandTarget="{Binding ElementName=reader}" >Üstünü çiz</Button>
            <Button Command="a:AnnotationService.ClearHighlightsCommand"
                CommandTarget="{Binding ElementName=reader}">Üstünü temizle</Button>
        </StackPanel>
        <FlowDocumentReader x:Name="reader">
            <FlowDocument>
                <Paragraph FontSize="22">Windows Client</Paragraph>
                <Paragraph FontSize="30">WPF 'in Form Dünyasındaki Yeri</Paragraph>
                <Paragraph>
                    <Figure Width="130" HorizontalAnchor="PageRight" VerticalAnchor="PageTop">
                        <BlockUIContainer>
                            <Image Source="Turhal11.jpg"/>
                        </BlockUIContainer>
                    </Figure>
                    …
                </Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>…</Paragraph>
                <Paragraph>
                    <Bold>Turhal Temizer</Bold>
                </Paragraph>
            </FlowDocument>
        </FlowDocumentReader>
    </StackPanel>
</Window>

C# kod
using System;
using System.IO;
using System.Windows.Annotations;
using System.Windows.Annotations.Storage;
using System.Windows;

namespace mak43
{
    public partial class Window10 : Window
    {
        FileStream stream;
        public Window10()
        {
            InitializeComponent();
        }
   
        private void Window_Initialized(object sender, EventArgs e)
        {
            //dipnotlar yükleniyor ve aktif yapılıyor.
            AnnotationService service = AnnotationService.GetService(reader);
            if (service==null)
            {
                stream = new FileStream("yedek.xml", FileMode.OpenOrCreate);
                    service = new AnnotationService(reader);
                AnnotationStore store = new XmlStreamStore(stream);
                store.AutoFlush = true;
                service.Enable(store);
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            //silinyor ve kaydediliyor.
            AnnotationService service = AnnotationService.GetService(reader);
            if (service!=null && service.IsEnabled)
            {
                service.Disable();
                stream.Close();
            }
        }
    }
}

Uygulamamızı derlediğimiz zaman sonuç ise aşağıdaki gibi olacaktır.



Sonuç oldukça başarılı. WPF ile FlowDocument ‘i kullanarak uygulama geliştirmenin ne kadar kolay yapıldığını gözlemlemiş olduk. Artık bizde birkaç haftalık çalışma ile kolayca bir New York Times Reader yapabiliriz.

Yazımızı sonuna gelmiş bulunuyor. Bu yazıda nelere değindiğimize kısaca açıklamak gerekirse, ilk olarak neden bu yazıyı yazacağımızı açıkladık, sonrasında yazı ve metin ile ilgili işlemleri ayrıntılı bir biçimde incelemeye çalıştık. Son olarak da FlowDocument kontrolünü inceleyerek WPF ile yapılmış Reader uygulamalarına benzer bir uygulama geliştirdik.

Eğer ki bizlerde kendimiz için Reader uygulaması geliştirmek istersek bunu nasıl yapabiliriz?” diye kafanıza soru takılabilir. Onu da kısaca açıklamak gerekirse, yukarıda değindiğimiz konular sizin bir Reader yapmanıza yetecek düzeydedir. Fakat verilerinizi elle değil de dinamik olarak dışarıdan alacağınız için bu yazıları ya XML ‘de tutmalı ya da veri tabanından çekmelisinizdir. Bu işlem için web servis oluşturmalı ve ulaştığınız içerikleri uygulamada kullandığınız kontrollere bind (bağlamak) etmeniz gerekecektir. Daha sonrasında ise gerçek bir Reader uygulamasına sahip olmuş olacaksınız.

Windows Presentation Foundation ile Data Binding işlemleri nasıl yapılıyor?” diye kafanızda bir soru var ise daha önce yayınlanmış olan makaleyi okuyabilirsiniz.

Umarım yararlı olmuştur.

Yazımızda değinmiş olduğumuz uygulamanın kaynak kodlarına linkten erişebilirsiniz.
turhal.temizer@csharpnedir.com

Çarşamba, Mayıs 14, 2008

WPF - Styles

Web programlama ile ilgilenenler CSS ‘in ne kadar yararlı olduğunu bilirler. Bilmeyenler için ise kısa bir bilgilendirme yapalım. Web sayfamızda kullanacak olduğumuz tasarımları, yazı fontlarını, renkleri ve daha birçok özelliği belirleyebildiğimiz dosyalardı. Daha sonrasından ise belirlemiş olduğumuz bu tasarımları gerekli yerlerde kullanarak hem zaman kaybından kurtulurken hem de web sayfamızda ekstra kod yazmaktan kurtuluyorduk.

Bu makalemizde Web uygulamalarından aşina olduğumuz stil işlemlerinin Windows Presentation Foundation ile nasıl yapabileceğimizi incelemeye çalışacağız.

Not: Visual Studio 2008 sp1 beta1 , .Net Framework 3.5 sp1 beta1 ve .Net Framework 3.0 sp2 beta1 12 Mayıs 2008 tarihinde bizlerin kullanımına sunulmuştur. Kullanmak isteyenler www.microsoft.com/download adresinden gerekli linki bularak indirebilirler. Fakat kurulması için sisteminizde kurulu olan beta ürünleri kaldırmanız gerekmektedir. Bu özellikle Silverlight 2,0 beta1 kullanan geliştiricileri ilgilendirmektedir. Beta ürünleri sildiğimizde geliştirme yapıyorsak nasıl devam edeceğiz derseniz ise SP1 beta1 ‘i kurduğunuz zaman silmiş olduğunuz yazılımlar geri yüklenecek ve diğer yazılımlarınızda eksikleri giderilmiş olarak bizlere sunulacaktır.

Stil işlemlerini uygulama üzerinden anlatmaya çalışacağız. Uygulamamızı ise Visual Studio 2008 ürünü ile gerçekleştiriyor olacağız. VS2008 ‘i olmayan geliştiriciler ise isterlerse Expression Blend veya C# Express Edition ile de yapacak olduğumuz uygulamaları yapabilmeleri mümkündür. Bahsettiğimiz herhangi bir ürün ile WPF application projesi oluşturarak stil işlemlerini incelemeye başlayabiliriz.

Stil işlemlerini incelerken uygulayacak olduğumuz senaryoyu özetlemek gerekirse. Ekranımızı kullanabileceğimiz iki sütuna bölerek bu sütunlara listbox ve buton kontrollerini ekleyeceğiz. Bu kontrolleri ve değerlerini ilk olarak bu kontrollere dâhil stil işlemleri ile daha sonrada style sınıfını kullanarak kontrollerimizde nasıl kullanabileceğimizi inceleyeceğiz.

Uygulamamızda kullanacak olduğumuz çalışma alanını iki sütuna bölüyoruz. Daha sonrada Listbox ve üç tane buton ekliyoruz.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
        <ListBoxItem>Deger 1</ListBoxItem>
        <ListBoxItem>Deger 2</ListBoxItem>
        <ListBoxItem>Deger 3</ListBoxItem>
        <ListBoxItem>Deger 4</ListBoxItem>
        <ListBoxItem>Deger 5</ListBoxItem>
    </ListBox>
    <StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
        <Button>Ekle</Button>
        <Button>Duzenle</Button>
        <Button>Sil</Button>
    </StackPanel>
</Grid>

Çalışacak olduğumuz alanının tasarımını belirledik. Şimdi ise eklemiş olduğumuz kontrollere en temel yöntemle tasarım ile ilgili özelliklerini aktarmaya başlayalım. Özelliklerimize ekranda nerede olacağına , köşe renklerine, arka plan renklerine ve yazı boyutlarını belirliyoruz. Ayrıca butonlara belirttiğimiz özelliklere ek olarak yazı stili de ekliyoruz. Sizler farklı yazı stilleri eklemek isterseniz XAML kod tarafında işlemlerinizi yapmak yerine form üzerindeki kontrollere ait özelliklerden font-family seçeneğinden bulabilirsiniz.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 1</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 2</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 3</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 4</ListBoxItem>
        <ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 5</ListBoxItem>
    </ListBox>
    <StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Ekle</Button>
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Duzenle</Button>
        <Button Foreground="DarkBlue" Background="LightSkyBlue"
                    FontSize="15" FontFamily="French Script MT">Sil</Button>
    </StackPanel>
</Grid>

Yukarıdaki kullanım biçimini sıkça uygulamalarımızda kullanıyorduk. Bu kullanım biçimini web uygulamalarında CSS kullanmadığımız zamanlarda görünen sayfaya tasarım bilgilerinin yazılması gibi kabul edebiliriz. WPF uygulamalarında ise bizim çalışma alanımızın dışında kalan bölümler stil dosyalarını belirleyeceğimiz bölümler olarak kullanacağız.

Eğer ki Expression Blend(EB) ile tasarım yapıyorsanız şimdi bahsedeceğimiz yönteme hiçte yabancı olmadığınızı fark edeceksiniz. Çünkü EB ile hazırladığınız tasarımlarda arka planda oluşturulmak olan XAML kodlar ekstra kod fazlalığını minimuma indirerek oluşturmaktadır. Bu sebepten ötürüde stil, animasyon gibi işlemlere ait kodları tek tek kontrollere eklemek yerine stil işlemleri stil sınıfına animasyon işlemlerini de Triggers sınıfına ekleyerek kullanmamızı sağlamaktadır.

Bizim hazırlayacak olduğumuz işlemlerin EB ile nasıl yapıldığını anlattıktan sonra şimdi bizde style sınıfını kullanarak tasarım işlemlerimizi miraslanabilir duruma getirebiliriz.

Penceremize ait özellikleri özkaynaklarında (resource) belirterek tekrardan kullanılabilir olmasına olanak tanıyoruz.



<Window.Resources>
    <Style x:Key="lb1" TargetType="ListBoxItem">
        <Setter Property="Margin" Value="0,2,0,3" />
        <Setter Property="Foreground" Value="Red" />
        <Setter Property="FontSize" Value="18" />
    </Style>
</Window.Resources>

Biraz önce kontrol içerisine eklemiş olduğumuz özelliklerin hepsini özkaynak olarak belirttik. Şimdi ise belirtmiş olduğumuz bu özkaynakları şimdi nasıl kullanacağımıza değinelim.

<ListBoxItem Margin="0,2,0,3" Foreground="Red" FontSize="18">Deger 1</ListBoxItem>

ListBox ‘a ait özellikleri en basit anlamda bu biçimde tanımlarken şu anda Style sınıfını kullanarak x:Key olarak belirlediğimiz attribute ‘e bağlayacağız.

<ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
    <ListBoxItem Style="{StaticResource lb1}">Deger 1</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 2</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 3</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 4</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb1}">Deger 5</ListBoxItem>
</ListBox>

ListBox kontrolünde değerleri tanımlamış olduğumuz ListBoxItem ‘ın özelliklerinde Style sınıfından tanımlanmış olan özelliğine statik olarak değeri bağlıyoruz.

Şimdi ise butonumuza ait özellikleri özkaynak olarak ayarlayalım. Style sınıfını kullanım yöntemine dikkat ettiyseniz standart olarak kontrollerde kullandığımız tasarım bilgilerini Setter sınıfının içerisinde özelliğini ve değerini belirleyerek kullanıyoruz. Setter ‘ın içerisinden tanımlamış olduğumuz özelliklere ilişkin değerler intellisence ile bize sunulmamaktadır. Bizler bu özelliklere ilişkin değerleri normalde kontrolün içerisinde kullanmış olduğumuz özelliklerden yararlanarak belirliyoruz.

Style kullanmadan önceki buton kontrolümüze ilişkin görüntü;

<Button Foreground="DarkBlue" Background="LightSkyBlue"
            FontSize="15" FontFamily="French Script MT">Ekle</Button>

Kullanmış olduğumuz style sınıfı;

<Style x:Key="ekleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>
    <Style x:Key="duzenleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>
<Style x:Key="silButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background" Value="LightSkyBlue"/>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>

Belirmiş olduğumuz stilleri biraz önce ListBox kontrolünden kullandığımız gibi bağlamamız gerekecektir. Yukarıdaki stil dosyalarını kontrol ederken kafanıza ufak bir soru takılabilir. “Stillerde kullanılan bütün özellikler aynı olduğundan tek bir stilin içerisinde kullanıla bilemiyormuydu ? “diyebilirsiniz. Tabii ki de benzerlik olduğu durumlardan tek bir stil sınıfında toparlamak mümkün olacaktır. Fakat daha sonra yapacak olduğumuz değişikliklerden ötürü üç buton içinde ayrı ayrı stil ayarladık.

Buton kontrollerimizde stilleri kullanma şeklimiz;

<StackPanel Grid.Column="1" Orientation="Vertical" VerticalAlignment="Top">
    <Button Style="{StaticResource ekleButon}">Ekle</Button>
    <Button Style="{StaticResource duzenleButon}">Duzenle</Button>
    <Button Style="{StaticResource silButon}">Sil</Button>
</StackPanel>

Temel olarak stillerimizi oluşturduk ve gerekli olan kontrollerimize bağlamalarını yaptık. Şimdi isterseniz ekran görüntüsünün nasıl gözüktüğüne göz atalım.



Stilleri daha önceden oluşturupta kontrollere bağladığımızda herhangi bir sorun oluşmadan kontrollerimizin gerekli stillerine kavuştuğunu görürüz. Ayrıca dikkatinizi çekmek istediğimiz bir nokta var. Uygulamamızda kullanacak olduğumuz stillere ilişkin özellikleri çalışma penceremizin özkaynaklarına eklemeden önce XAML kod tarafımızın çok karmaşık olduğunu görürüz. Stillere ilişkin bilgileri özkaynak sınıfının içerisine eklediğimizde ise hem XAML kod tarafında oluşan karmaşık görüntüyü ortadan kaldırdı hem de bizleri aynı özellikleri defalarca kez yazmaktan kurtardı.

Şimdi ise düzenle ve sil butonlarımıza ilişkin stil özelliklerinde ufak değişiklikler yapalım. Sil butonunun dikkat çekmesi için yazı renklerini rengini kırmızı, düzenle butonunki ise yeşil olarak belirleyelim.

<Style x:Key="duzenleButon" TargetType="Button">
    ***
    <Setter Property="Foreground" Value="DarkGreen"/>
    ***
</Style>
<Style x:Key="silButon" TargetType="Button">
    ***
    <Setter Property="Foreground" Value="Red"/>
    ***
</Style>

Butonlara ilişkin stil özelliklerinde bu ufak değişiklikleri yaptıktan sonra uygulamamızı tekrardan çalıştırdığımızda değişikliklerin uygulandığını göreceksiniz.

ListBox kontrollerinde kullandığımız bütün kontrollere aynı stil sınıfını bağlamıştık. Şimdi ise hepsi için ayrı ayrı stiller oluşturacağız. Ekleyecek olduğumuz stiller de ana özellikler aynı olmakta birlikte yalnızca yazıların renklerini değiştireceğiz.

<Style x:Key="lb1" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Red" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb2" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Blue" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb3" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Green" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb4" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Yellow" />
    <Setter Property="FontSize" Value="18" />
</Style>
<Style x:Key="lb5" TargetType="ListBoxItem">
    <Setter Property="Margin" Value="0,2,0,3" />
    <Setter Property="Foreground" Value="Cyan" />
    <Setter Property="FontSize" Value="18" />
</Style>

Özelliklerini değişitirdiğimiz listbox stillerini tek tek kontrollerine bağlamamız gerekmektedir. Onu da aşağıdaki gibi yapıyoruz.

<ListBox Width="200" Height="150" Grid.Column="0" VerticalAlignment="Top">
    <ListBoxItem Style="{StaticResource lb1}">Deger 1</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb2}">Deger 2</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb3}">Deger 3</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb4}">Deger 4</ListBoxItem>
    <ListBoxItem Style="{StaticResource lb5}">Deger 5</ListBoxItem>
</ListBox>



Stil işlemlerini yaparken kafamıza şöyle bir soru takılabilir. “Tek bir stil sınıfında tanımlamış olduğumuz özellikleri diğer stil sınıflarına özelliklerini miraslayamaz mıyız?”. Bu sorunu cevabı tabii ki de evet olacaktır. Çünkü dikkat sizlerde dikkat etmişsinizdir ki hem ListBox kontrolü için hem de Buton kontrolü için hazırmış olduğumuz stillerde birbirlerini tekrarlayan özellikler oldukça fazladır. Bizlerde bu tür işlemleri uygulamalarımızda daha az kod yazabilmek için yaptığımızdan dolayı farklı çözüm yolları üretmemiz gerekecektir. Style sınıfının özelliklerini incelediğimizde Baseon özelliği dikkatimizi çekmektedir. Bu özellik başka bir stil sınıfındaki özellikleri kullanıldığı sınıfa miraslayabilmeye olanak tanıyor. Miraslama işlemini ise hazırlamış olduğumuz stilleri kontrollere bağladığımız biçimde kullanacağız.



Stillerde yer alan benzer özellikleri sadece tek bir stil sınıfında kullanarak diğer stil sınıflarına miraslama yani bağlama yapacağız. Bu işlemleri aşağıdaki gibi yapabilmemiz mümkündür.

<Window.Resources>
    <Style x:Key="lb1" TargetType="ListBoxItem">
        <Setter Property="Margin" Value="0,2,0,3" />
        <Setter Property="Foreground" Value="Red" />
        <Setter Property="FontSize" Value="18" />
    </Style>
    <Style x:Key="lb2" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Blue" />
    </Style>
    <Style x:Key="lb3" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Green" />
    </Style>
    <Style x:Key="lb4" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Yellow" />
    </Style>
    <Style x:Key="lb5" TargetType="ListBoxItem" BasedOn="{StaticResource lb1}">
        <Setter Property="Foreground" Value="Cyan" />
    </Style>
    <Style x:Key="ekleButon" TargetType="Button">
        <Setter Property="Foreground" Value="DarkBlue"/>
        <Setter Property="Background" Value="LightSkyBlue"/>
        <Setter Property="FontSize" Value="15"/>
        <Setter Property="FontFamily" Value="French Script MT"/>
    </Style>
    <Style x:Key="duzenleButon" TargetType="Button" BasedOn="{StaticResource ekleButon}">
        <Setter Property="Foreground" Value="DarkGreen"/>
    </Style>
    <Style x:Key="silButon" TargetType="Button" BasedOn="{StaticResource ekleButon}">
        <Setter Property="Foreground" Value="Red"/>
    </Style>
</Window.Resources>

Değişikleri yaptıktan sonra kodlarımızın ne kadar azaldığına görüyoruz. Bu sayede hem çalışma alanımızın boyutu küçüldü hem de bizler tekrardan stilleri düzenlemek istediğimizde çok daha kolay bir biçimde bu işlemi yapabilir duruma geldik.

Yaptığımız değişiklikler sonucunda ekran görüntüsünde ise herhangi bir değişiklik olmamıştır.



Son olarak butonlara iki farklı renkten oluşan arka plan stili ayarlayacağız. Bunu yapabilmemiz için stil sınıfında Background özelliğinin alt özelliklerinden olan LinearGradientBrush yararlanacağız. Ayrıca bir buton üzerinden değişiklik yaptığımız diğer butonlar o butonun özelliklerine bağlı olduğu için değişiklikler otomatik olarak aktarılacaktır. Bu sebepten ötürü yalnızca ekleButon stili üzerinde değişiklik yapıyoruz.

<Style x:Key="ekleButon" TargetType="Button">
    <Setter Property="Foreground" Value="DarkBlue"/>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientStop Offset="0" Color="CornflowerBlue"/>
                <GradientStop Offset="1" Color="Bisque"/>
            </LinearGradientBrush>
        </Setter.Value>
    </
Setter>
    <Setter Property="FontSize" Value="15"/>
    <Setter Property="FontFamily" Value="French Script MT"/>
</Style>

Yapmış olduğumuz değişiklik sonucunda ekran görüntümüz ise aşağıdaki gibi olmuştur.



Stil işlemleri ile birlikte tasarımlarımızı ekleyebileceğimiz iki yöntem daha bulunmaktadır. Kısaca bu iki yönteme değinmeye çalışalım. Bunlardan birincisi yazımızda da değinmiş olduğumuz window.resource çalışma alanımızın özkaynaklarıdır. Bu sınıf içerisinde style dahil olmak üzere birçok özelliği saklayabilmemiz mümkündür. En sık olarak kullanılan yöntemde yaptığımız tasarımları özkaynak olarak saklamaktır. Çünkü uygulama çalıştırıldığında bu sınıf içerisindeki değerler kullanılmak üzere belleğin bir köşesinde tutulduğundan ötürü animasyon ve tasarım işlemlerinin kullanılması esnasından bu iki işlemden kaynaklanan performans kaybını minimuma indirgeyecektir.

Kullanabileceğimiz bir diğer yöntem ise ControlTemplate ‘dir. Kullanıcı arayüzünde sıklıkla kullanılacak olan kontrolleri stilleri ile birlikte tanımlamamıza olanak tanımaktadır. İşlevi ise UserControllere oldukça fazla benzemektedir. Daha sonraki yazılarımızda ControlTemplate 'e ilişkin özelliklere değinmeye çalışacağız.

Sonuç olarak yazdıklarımızı toparlamak gerekirse, stil işlemlerini neden kullanmamız gerektiğine değinerek yazımıza başlamıştık. Sonrasında en acemi yöntem ile kontrollerimize tasarımsal özellikler ekledik. Bu özellikleri eklediğimizde XAML kod tarafının ne kadar karmaşıklaştığını ve kullanacak olduğumuz kontrol sayısının 3 - 5 değil de 100-200 olduğu durumlarda içinden çıkılamayacak bir durum oluşacağını göz önüne alarak kullanmış olduğumuz tasarım özelliklerini stil sınıfının özelliklerine nasıl kullanacağımıza değindik. En son olarak stil sınıflarında benzer olarak kullanılan özelikleri yalnızca bir kez tanımlayarak diğer stil sınıflarına nasıl miraslayacağımız gördük.

Umarım yararlı olmuştur.

Yazımızda değinmiş olduğumuz uygulamanın kaynak kodlarına linkten erişebilirsiniz.

Pazar, Nisan 20, 2008

WPF – Uygulamalara Video Kontrolleri Eklemek

2005 yılında Windows Presentation Foundation ile ilgili söylentiler ortaya atıldığında, Adobe Flash ile yapabildiğimiz bütün işlemleri ve daha fazlasını masaüstü ve web uygulamalarında yapabileceğimizden söz edilmişti. Daha sonra .Net Framework 3.0 ‘ın ilk sürümleri olarak .Net FX bizlere sunulduğundan bu söylentilerin gerçekleşebileceği düşünceleri zihnimizde canlanmaya başlamış ve özellikle masaüstü uygulamalarda devrim niteliği taşıyabileceğini düşünmeye başlamıştık. Belirli zaman geçtikten sonra WPF ‘i yalnızca masaüstü uygulamalar için kullanılacağına ve web uygulamalarının isminin de Microsoft Silverlight olacağını gözlemlemiş olduk. WPF ile de web uygulamaları yayınlamak hala mümkün olmakta ve bu tür uygulamalara da XBAP uygulamalar denilmiştir. Web tarafında Silverlight ‘ın estirdiği fırtınayı masaüstü uygulamalarında da WPF gerçekleştirmeye başlamıştı.

WPF ile gelen ve dünya da en çok kullanılan ürünler ile Windows Vista, Office System 2007 ve Windows Live Messenger 8.0 ve sonrası olmuştur. Karşımıza gelen bu ürünlerin ortak özellikleri tasarımlarının bir önceki sürümlerine oranla inanılmaz değişikler gösterebilmiş olmasıdır. Özelliklere kısaca örnek vermek gerekirse, Windows Vista ile izleyeceğimiz bir videoyu herhangi bir oynatıcı açmadan izleyebiliyor olmamızdır. Bu ve bunun gibi birçok işlemin ana özelliği uygulamalarımızda yer alan kontrolleri dinamik bir biçimde kullanabiliyor olmamızdır.



Windows Vista ile nasıl video kontrollerini kullanıldığını yukarıdaki ekran görüntüsünden bakabiliriz. Son kullanıcılar bu tür kontrolleri kullandıkça bizlerden geliştirmemizi istedikleri uygulamalarda bu tür kullanım kolaylıklarının olmasını istemektedirler. Bizlerde bu tür istekleri uygulamamızın performansını da düşünerek gerçekleştirmeye çalışırız.

Windows kontrollerinin daha iyileştirilmiş ve yeni nesil sistemler ile uyumlu olabilmesi açısından WPF ile geliştirmek bizler için her daim ayrıcalıklı bir durum olacaktır. Ayrıcalıklı durumdan kastımız, uygulamalarımızda ne kadar en son teknoloji kullanırsak son kullanıcılar tarafında o kadar coşku uyandırırız. Müşteri memnuniyetine dayalı bir dünyada yaşadığımız içinde bu bize çok daha fazlası ile katma değer olarak geri dönecektir.

Kısaca neden yeni kontrolleri kullanmamız gerektiğini ve bu kontrollerden video kontrolünün Windows Vista işletim sistemi ile nasıl gözüktüğüne göz attıktan sonra bu makalemizde değinecek olduğumuz WPF uygulamalarına Media kontrollerinin eklenmesi konusunu incelemeye başlayabiliriz.

Win32 uygulamalarımızı dijital Media kontrollerinin eklemenin iki yolu vardır. Bunlardan birincisi animasyon işlemlerini daha canlı göstermek ve video kontrollerini uygulamalarımızda kullanmak için başvurduğumuz DirectShow Api leridir. Bir diğeri ise Windows Media Player ActiveX kontrolüdür. Bu iki kontrolü de uygulamamıza gömülü bir biçimde uygulamalarımızda kullanabiliyoruz.

“Peki, bu iki kontrol varken neden WPF ‘te kullanılmakta olan kontrollerin bizlere sunulduğu” sorusunun cevabını araştırmaya çalışalım. DirectShow ile geliştiricilere Media uygulamaları için inanılmaz fazlalıkla imkânlar sağlanmaktadır. Tabii bu imkânları kullanabilmemiz için bu api hakkında geniş bir bilgi yelpazesine sahip olmamız gerekiyordu. Uygulamalarımızda yalnızca tek bir video göstermek içinde geliştiricilere bu api hakkında geniş bilgi düzeyine sahip olmalarını istemek geliştiriciler için oldukça sıkıcı bir durum oluyordu.

WPF ‘de ise DirectShow api lerinde yer alan kontrollerinin benzerlerini .Net Framework 3.0 ile birlikte gelen özellikler ile rahatlıkla gerçekleştirebilmemiz mümkündür. WPF ile gelen kontrolleri de Win32 uygulamalarında sorunsuzca kullanabiliriz.

Media oynatmak içinde Windows Media Player ActiveX kontrolüne ait özelliklere hâkim olmamız gerekmektedir. Yine geliştiricilere ekstra bir şeyler öğrenmeye zorlamak yerine WPF ile .Net Framework yapısına eklenen MediaElement kontrolü yardımı ile bu işlemleri de sorunsuzca gerçekleştirebilmemiz mümkündür. Kullandığımız bu kontrol yardımı ile videolarımızı 3D yüzeylerdeymiş gibi de kullanabilmemiz mümkündür.

Ses ve Media kontrollerini geliştiriciler kullanmak istediğinde WPF ile sunulan Media özellikleri olduğundan bahsetmiştik. Bu Media özelliklerini kullanmak istediğimizde arka planda Media Player işlemini başlatarak işlemlerimizi gerçekleştirebilmemize olanak sağlanmaktadır. WPF uygulaması açıldıktan sonra Media uygulaması olan sayfada yer alan Media dosyası yüklendikten sonra Media Player ‘ın açabileceği bir format olup olmadığını kontrol ediyor. Eğer bu formatlar dışında bir dosya açmak istiyorsak uygulama bizden codec yüklememizi istemektedir.

Media uygulamaları olan uygulamalarımızdaki dosyalar gösterilirken arka planda dosyalarımızın yüklenmesine devam edilmektedir. Bu yüklenme işlemi biz video ‘yu duraklatsak bile yüklemeye devam edecektir. Video ‘nın yüklenmesini engellemek için yapmamız gereken işlem tamamen durdurmak olacaktır. Ayrıca, ses dosyalarını çaldırabilmemiz için System.Media.SoundPlayer sınıfını da kullanabilmemiz mümkündür.

MediaElement Kontrolünün Kullanılması

Windows Presentation Foundation ile Media dosyalarını göstermenin oldukça kolay olduğundan ve bu tür işlemleri yapabilmek içinde MediaElement kontrolünün gerekli olduğundan üst paragraflarda bahsetmiştik. Bu kontrolü XAML kod tarafında ekleyebileceğimiz gibi C# veya VB.Net kod tarafında MediaElement kontrolünü aktifleştirerek kullanabilmemiz mümkündür. MediaElement kontrolünü uygulamalarımızda kullanırken ya bağımsız olarak kontrollerimizden aldığımı değeler yönetiriz ya da sistem saatinden alarak işlemlerimizi yapmamıza olanak tanıyacaktır.

Bağımsız durumda Media elementi nasıl kullanacağımıza göz atalım;

XAML
<MediaElement Source="Forza.wmv" Width="320" Height="240" LoadedBehavior="Play" />

XAML kod bloğunu uygulamamıza yazıp derlediğimiz zaman uygulamamızın içerisinde videomuzun görüntülendiğine tanık olacağız.

Not: Eğer videonuzun yolunu doğru bir şekilde belirttiğiniz halde gözükmediyse muhakkak projenizin oluştuğu klasörün altında yer alan Debug dizininin altında izlettireceğiniz videonun yer almasına dikkat ediniz.

MediaElement kontrolünün performans açısından çok daha fazla olanaklarının olduğundan ve diğer Api lere oranla işlemciyi daha az yoracağından bahsetmiştik. Şimdi bu söylemlerimizi doğrular nitelikteki ekran görüntülerini veriyoruz. Bu ekran görüntüsünde MediaElement yardımı ile oluşturduğumuz videonun yanında görev yöneticisi yer almaktadır.



MediaElement kontrolümüzü kullanarak çok basit anlamda bir uygulama geliştirdik ve bu uygulamamızı görüntüledik. Şimdi yapacağımız örnekte ise başlat, duraklat, bitir sessiz butonlarının olduğu bir örnek olacaktır. Bu örneğimizde kontrolleri XAML kod tarafında hazırlarken kontrollere verilecek olan görevleri C# kod tarafında oluşturuyor olacağız. Ayrıca kontrollerimizin kullanıcılar tarafından kullanıldığından videoyu kontrol edebilmesi için LoadBehavior özelliğine Manual ‘i atayacağız.

XAML
<Window x:Class="WpfMedia.Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="MediaElement Makale" Height="800" Width="600">
   <Grid>
      <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
         <MediaElement Name="MediaMakale" Source="Forza.wmv"
            LoadedBehavior="Manual" Width="320" Height="240" />
         <StackPanel Orientation="Horizontal" Margin="0,10,0,0">
            <Button Content="Oynat" Margin="0,0,10,0"
               Padding="5" Click="mediaOynat" />
            <Button Content="Duraklat" Margin="0,0,10,0"
               Padding="5" Click="mediaDuraklat" />
            <Button x:Name="sessizButton" Content="Sessiz"
               Padding="5" Click="Sessiz" />
         </StackPanel>
      </StackPanel>
   </Grid>
</Window>

C#
susing System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfMedia
{
   public partial class Window1 : System.Windows.Window
   {
      public Window1()
      {
         InitializeComponent();
         mediaMakale.Volume = 100;
         mediaMakale.Play();
      }

      void mediaOynat(Object sender, EventArgs e)
      {
         mediaMakale.Play();
      }

      void mediaDuraklat(Object sender, EventArgs e)
      {
         mediaMakale.Pause();
      }

      void mediaMute(Object sender, EventArgs e)
      {
         if (mediaMakale.Volume == 100)
         {
            mediaMakale.Volume = 0;
            sessizButton.Content = "Sesli";
         }
         else
         {
            mediaMakale.Volume = 100;
            sessizButton.Content = "Sessiz";
         }
      }
   }
}



MediaElement, zaman durumuna bağlı olarak Windows Presentation Foundation ‘ta yer alan animasyon mimarisine bağlı olarak ta kullanılabiliyor. Zaman durumunu aktifleştirdiğimizde MediaElement ‘in özelliklerinden olan MediaTimeline ve MediaClock özelliklerine başlangıç ve ilerleme değerleri aktararak kullanabiliyoruz. Uygulamalarımızda başlangıç zamanı ve hangi zaman aralıkları ile ilerleyeceği ile ilgili özellikler Windows Presentation Foundation ‘da animasyon işlemlerini yaparken kullandığımız StoryBoard üyesine benzemektedir. Bu üyeyi de kullanırken belirli bir başlangıç zamanı, ilerleme zamanı ve sonlanma zamanı belirtebiliyorduk. Şimdi bu tür zamana bağlı kontrolleri kullanmak istediğimizde uygulamamızda ne tür bir kod bloğu kullanabileceğimize değinmeye çalışalım.

XAML
<MediaElement Name="mediaMakale" Width="320" Height="240" />
   <Grid.Triggers>
      <EventTrigger RoutedEvent="Grid.Loaded">
         <EventTrigger.Actions>
            <BeginStoryboard>
               <Storyboard Storyboard.TargetName="mediaMakale">
                  <MediaTimeline Source="Forza.wmv"
                     BeginTime="00:00:00" Duration="00:05:00" />
               </Storyboard>
            </BeginStoryboard>
         </EventTrigger.Actions>
      </EventTrigger>
   </Grid.Triggers>

Uygulamalarımızda MediaTimeline özelliğini kullanmak yerine MediaElement kontrolünü kullanmak ileride gerçekleşebilecek sorunları ortadan kaldırmak açısından çok daha yararlı olacaktır. Çünkü MediaTimeline ile uygulamalarımızı çalıştırmak istediğimizde arkada MediaElement kontrolü oluşturulmak istenecek ve istek sonrasından belirli zaman aralıklarında önbelleğe alacaktır. Sürekli çağırılan video dosyaları uygulamalarımızı web tabanlı yaptığımız durumlarda performans kaybına uğrayabilmekte ya da Windows tabanlı olarak geliştirdiğimiz uygulamalarda çok büyük dosyalı uygulamaları göstermek istediğimizde hatalar verebilecektir. Fakat aklımıza başka bir soru takılabilir. “O da çok büyük boyutlu bir videoyu birden önbelleğe aldırarak oynat dediğimizde performans kaybı yaşamayacak mıyız?” olacaktır. İşte bu sorunu engellememiz için MediaElement kontrolü içerisinde video dosyalarımızı oynatıyoruz. MediaElement kontrolünün Media dosyalarını çalıştırma mantığı minimum sistem zorlaması ile maksimum performans alabilmektedir. Diğer durumlarda biz yönetmeye çalışırsak, WPF öncesi durumlarda olduğu gibi oldukça zprlanabilir ve işlemlerimizi yaparken büyük sorunlar yaşabiliriz.

MediaPlayer Sınıfının Kullanılması

MediaElement kontrolünün özelliklerinde çok fonksiyonlu özellikler yani, yeniden oynatma, çalma listesi gibi özellikler yer almamaktadır. MediaElement üzerinde yer alan kontrollerimize daha çok fonksiyonellik kazandırmak istediğimizde MediaPlayer sınıfını kullanabiliriz. MediaElement ile video ve benzeri Media dosyaları oynatmak istediğimizde arka planda Media Player işleminin başlatıldığından ve bu işlemler üzerinden videomuzu oynattığından bahsetmiştik. İşte bu sebepten ötürü uygulamalarımızda MediaPlayer sınıfını kullanmak performans kaybı yerine son kullanıcıya sunacağımız birçok özelliği kolaylıkla sunabilme olanağı tanımaktadır.

MediaPlayer sınıfını kullanmamız için uygulamamızda System.Windows.Media isim alanının kullanılıyor olmasına dikkat etmemiz gerekmektedir. Şimdi ise C# ile Media Player sınıfını nasıl kullanabileceğimize ilişkin bir örnek vereceğiz.

C#
MediaPlayer mp = new MediaPlayer();
   Try {
      mp.Open(new Uri("mediaMakale.wmv"));
      }
     catch(Exception ex) {
    MessageBox.Show(ex.Message);
}

Media Player sınıfı ile kullanabildiğimiz özellikler ve üyeler MediaElement kontrolünün içerisinde kullanılabilmektedir. MediaElement ve Media Player uyumu ile gerçekleştirdiğimiz uygulamalarda yalnızca HD videoların gösterilmesinde sorunlar çıkmaktadır. Bu sorunlarda sistem özelliklerimizden olduğu düşünülmektedir. Çünkü ekran kartı iyi bir sistem ile uygulamamızı çalıştırdığımızda herhangi bir sorun ile karşılaşmazken, daha düşük özellikleri sistemlerde denediğimizde hatalar verebilmektedir. Media Player sınıfı videolarımızı çalıştırırken VideoDrawing sınıfı yardımı ile bu işlemleri yapmaktadır. 3D yüzeylerde de video izlemek istediğimizde Media Player sınıfı yine VideoDrawing sınıfı yardımı ile kolaylıkla video dosyalarını gösterebilmektedir.

Media Player sınıfında MediaElement kontrolünde olduğu gibi direk yolu gösterebilmek yerine uri özelliği ile yolunu uygulamamızın içerisindeki yolunu belirtiyoruz.

WPF Kontrollerinde Gömülü Videoların Kullanımı

MediaElement kontrolü System.Windows.UIElement sınıfından miraslanarak oluşturulmaktadır. Miraslamadan ötürü bir kontrolü başka bir kontrolün içerisinde de kullanabilmemize olanak tanınmıştır. Bizde bu özelliği test edebilmek için Button kontrolünün içerisinden MediaElement kontrolünü çalıştırmayı deneyeceğiz. Bunun için XAML kod tarafına aşağıdaki kodları ekliyoruz.

XAML
<Button Name="videoButton" Click="videoButton_Click"
   Width="320" Height="240">
   <MediaElement Name="forzaVid" Source="Forza.wmv"
       LoadedBehavior="Play" Width="320" Height="240" />
</Button>



Bu uygulamamızı derlediğimiz anda video oynamaya başlamaktadır. Bunun sebebi LoadedBehavior özelliğine Play değerini atmamızdan kaynaklanmaktadır. Eğer ki biz uygulama başlar başlamaz değil de Butona tıklandığı zaman videoyu başlatmak istersek Button_onClick özelliğine MediaElement ‘e vermiş olduğumuz isim ile forzaVid.Play(); kodunu eklememiz yeterli olacaktır. Bu değişiklik sonrasında uygulamamız butona tıklandığı anda, buton içerisinde video gösteren bir hal almış olacaktır. Bu tür ince detaylar son kullanıcılara sunulacak olan uygulama kullanım zevkini maksimuma çıkaracağı kaçınılmaz bir gerçektir.

Islak Zemin Yansıması Teknikleri

Uygulamalarımızda suda ya da camda karşılaştığımız yansıma işlemlerini yapmaya çalışırken fazlaca zaman kaybına uğrardık. WPF ile bu işlemleri yapmak istediğimizde ise VisualBrush üyesine MediaElement ‘i bağlamamız yeterli olacaktır. Daha sonrasında ise, VisualBrush içerisinden yapacağımız ince detaylar ile yansıma işlemini gerçekleştirebiliriz.

Yansıma işlemlerini nasıl yaptığımız konusunda kafanızda herhangi bir soru işareti oluşursa daha önceki WPF makalelerimizi okuyabilirsiniz.

Şimdi ise ıslak zemin yansıma efektine benzeyen uygulamamızı yapmamıza yarayacak olan kodlarımızı verelim.

XAML
<Window x:Class="WpfMedia.Window3"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="WPF Makale" Height="340" Width="350">
      <Grid x:Name="Grid">
         <StackPanel VerticalAlignment="Center">
            <MediaElement Name="Vid" Source="Forza.wmv"
               LoadedBehavior="Play" Width="320" Height="240" />
            <Rectangle Width="320" Height="240">
               <Rectangle.Fill>
                  <VisualBrush Visual="{Binding ElementName=Vid}" />
               </Rectangle.Fill>
               <Rectangle.OpacityMask>
                  <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                     <GradientStop Color="#AA000000" Offset="1" />
                     <GradientStop Color="#00000000" Offset="0" />
                  </LinearGradientBrush>
               </Rectangle.OpacityMask>
            <Rectangle.RenderTransform>
         <TransformGroup>
         <ScaleTransform ScaleY="-1" />
         <TranslateTransform Y="242" />
      </TransformGroup>
   </Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
</Grid>
</Window>



Bu uygulamamızı da basitçe yapmış oluyoruz.

Uyumlu Ses Dosyalarının WPF Uygulamalarına Eklenmesi

WPF uygulamalarımıza MediaElement kontrolü yardımı ile birçok video ekledik ve eklediğimiz bu videoları form kontrollerinin içerisine bile ekleyebildik. Fakat dijital dünya sadece görüntüden ibaret değildir. Birde bu dünyada sesler yer almaktadır. Şimdi de ses dosyalarını nasıl WPF uygulamalarımıza ekleyebileceğimize değineceğiz.

Ses dosyalarımızı uygulamalarımızda kullanabilmemiz için System.Windows.Media isim alanı altında tanımlı olan sound Player sınıfını kullanacağız. Bu sınıfta Media Player ile çalabildiğimiz ses dosyalarımızı WPF uygulamalarımız da çalabilmemiz mümkündür. Ayrıca Media Player için varsayılan ses formatı olan WAV ‘ı da sorunsuzca çalıştırabilmektedir.

SoundPlayer sınıfını kullanırken bu sınıfın metotlarından olan SoundPlayer.Play(); metodu yardımı ile de ses dosyalarını yürütebilmemiz mümkündür. Tabii yürütebilme özelliği ile birlikte duraklatma ve sonlandırma metotları da yer almaktadır.

Şimdi uygulamalarımızda SoundPlayer özelliğini kullanabileceğimiz örnek için gerekli olan kod parçacığına göz atalım.

XAML
<EventTrigger RoutedEvent="Button.MouseEnter" SourceName="Button">
   <EventTrigger.Actions>
      <SoundPlayerAction Source="ses/lake.wav"/>
   </EventTrigger.Actions>
</EventTrigger>

Uygulamamızı derlediğimizde ses dosyamız sorunsuz bir biçimde çalacaktır.

Bu yazımızda nelere değindiğimizi toparlamak gerekirse, ilk olarak WPF ile geliştirilmiş ve günümüzde en çok kullanılan uygulamalara değindik ve bu uygulamalardan Windows Vista ‘da MediaElement kontrolünü nerede kullanıldığına göz attık. Sonrasında ise MediaElement kontrolü kullanılarak yapılmış farklı uygulamaları incelemeye çalıştık.

Sonuç olarak en temel anlamda MediaElement kontrolünü kullanarak video dosyalarını nasıl kullanabileceğimize incelemeye çalıştık.

Umarım yararlı olmuştur.

Yazımızda değinmiş olduğumuz uygulamanın kaynak kodlarına linkten erişebilirsiniz.

turhal.temizer@csharpnedir.com