Teknolojinin gelişmesiyle bilişim sektörü artık daha çok mobil sektöre kayar oldu. Intel mobil dizüstü bilgisayarlar için daha az güç tüketimli Haswell
işlemcisi üretiyor, öte yandan Nvidia, Las Vegas'taki CES fuarında tanıttığı 192 çekirdekli Tegra K1 işlemcisi ile oyun piyasasını mobil tarafına kaydırmak
niyetinde.

Durum böyleyken geliştiriciler de artık masaüstü uygulamaları yerine artık mobil uygulamalar üretmek istiyorlar. Ben de yeni başladığım Windows Phone 8
(WP8) geliştirimi serüvenimde elde edindiğim bilgileri bu yazımda aktarmaya çalışacağım.
WPF ve XAML üzerinde geliştirim yapanların WP8'e daha kolay alışacaklarına eminim. Fakat ne kadar Windows Phone uygulamalarının görünümü WPF uygulamalarına
benzese bile kullandığınız mobil cihazın donanım kısıtlamalarından dolayı PC'de yaptığınız her atraksiyonu Phone'da aynı şekilde yapamayabilirsiniz. Buna
rağmen Phone uygulamaları geliştirmek oldukça keyifli.
Hazırlık Aşamaları
Öncelikle Windows Phone 8 uygulaması geliştirebilmemiz için sisteminizin 64-bit Windows 8 veya üstü olması gerekiyor. Çünkü Windows Phone 8 emülatörü daha
özel donanım, yazılım ve yapılandırma gereksinimleri istiyor. Bu yüzden Windows 7 veya daha alt bir versiyona sahip işletim sisteminiz varsa WP8
uygulamalarını geliştirebilmeniz mümkün değil.
Ayrıca Visual Studio'nun kurulu olması gerekiyor. Visual Studio 2013'ün
90 günlük deneme sürümünü
indirebilirsiniz.
Eğer önceden sisteminizde Visual Studio 2012 Professional ve üstü yüklü ise Phone SDK 8.0'ı indirmenize gerek yok çünkü zaten entegre bir şekilde geliyor.
Fakat daha eski bir Visual Studio sürümünü kullanıyorsanız
SDK'yı indirmeniz gerekecektir.
"Emülatör yerine kendi Windows 8 telefonumu kullanayım." diyorsanız bunun için bir
geliştirici hesabınızın olması gerekiyor. Geliştirici hesabı için belirli bir ücret ödemeniz
gerekiyor. Şu an için bireysel geliştiriciler 37 lira, şirket sahipleri 160 lira civarında bir meblağ ödeyerek hesap açabilirler.
Başlangıç için:
1. Öncelikle Visual Studio'yu açalım ve üst menüden
File -> New Project'i seçelim.
2. Yeni Proje penceresinde sol taraftaki yüklü
Template'lerden
Visual C# ->
Windows Phone'u seçtiğimizde orta menüde birçok proje
türlerinin sıralandığını görebiliriz.
|
Windows Phone App
|
Tek sayfalık basit uygulamalar oluşturmak içindir. Herhangi bir uygulamaya başlamanın en kolay yolu bu tür proje şablonu kullanmaktır.
|
|
Windows Phone Databound App:
|
İçerisinde bir liste ve gezinti elemanlarının yer aldığı temel bir MVVM(Model-View-View-Model) uygulamasıdır.
|
|
Windows Phone Class Library:
|
Bir arayüzü (UI) olmayan, sınıf kütüphaneleri oluşturmak için özelleşmiş bir şablondur.
|
|
Windows Phone Panorama App:
|
Windows 8'deki başlangıç menüsünde olduğu gibi Panaroma control içeren uygulamalar oluşturmanızı sağlar.
|
|
Windows Phone Pivot App:
|
Uygulama içerisinde bir başlık ve gövde kısmından oluşan, sayfalar arasında gezinebilmenizi sağlayan bir uygulama türü oluşturmak için
özelleşmiştir.
|
|
Windows Phone XAML and Direct3D App
|
C++ bileşenleriyle 3D uygulamalar oluşturmanızı sağlar.
|
|
Windows Phone XAML and XNA App
|
XNA çatısı altında Phone için oyun uygulamaları oluşturmanızı sağlar.
|
|
Windows Phone HTML5 App
|
Adından da anlaşılacağı gibi HTML5 bileşenleri içeren bir uygulama oluşturmanızı sağlar.
|
|
Windows Phone Audio Playback Agent
|
Ses içeren uygulamalar oluşturmak için bu kod kütüphanesini kullanabilirsiniz.
|
|
Windows Phone Audio Streaming Agent:
|
Bu da rolü akış seslerini oynatma için bir kütüphanedir.
|
|
Windows Phone Scheduled Task Agent
|
Eğer uygulamanızda belirli aralıklarla bir bildirim veya web servis isteği yapmak istiyorsanız, bu kütüphaneyi kullanmalısınız.
|
Biz şimdilik bu şablonlardan en kolay olanını
Windows Phone App'i seçelim. Aşağıda
Name: kısmını
HelloWorld olarak değiştirelim.
OK butonuna tıkladıktan sonra hangi Windows Phone işletim sistemi altında uygulama yapmak istediğimizi soracak.
Windows Phone OS 8.0
uygulaması geliştireceğimiz için bu Alana dokunmadan
OK dediğimizde Visual Studio bizim için gerekli dosyaları oluşturacak ve
MainPage.xaml
dosyasını görüntüleyecek.
MainPage.xaml dosyasının içeriğine daha yakından bakalım:
3. ve 8. satırlar arasında 6 tane
schema tanımlanmış. Bileşenleri kullanacağımız zaman öncelikle bu şekilde şemalarını tanıtmalıyız. Her tanımlanan
şemayı kullanmak için ise
xmlns özelliğini kullanmalıyız ve her
xmlns özelliğini kullanmak için o şemayı bir
namespace ile belirtiriz
(Örneğin: xmlns
:phone şeklinde). "Fakat 3. satırda bir kolon tanımlaması yapılmamış." diye düşünülebilir.
Evet bu doğru burada bir namespace tanımlaması yapmadık çünkü bu satırda belirtilen, uygulamamızı XAML namespace'i ile eşleştirmemizi sağlayan ve
varsayılan olarak tanımlanan şemamızdır. XAML şemaları ağaç yapısında olduğu için bu bir
Root şemasıdır ve diğer
child şemaların birer
namespace ile belirtilmesi gerekir.
4-8.nci satırlar arasında ise diğer çocuk şemalar yer almakta. Eğer uygulamalarımızda harici bir bileşen kullanırsak ve o bileşen için ayrılan şemanın
tanımlaması yapmazsak oluşturduğumuz XAML dökümanı geçersiz/bozuk olur. Bozuktan kastım, derleyici o bileşenin hangi namespace'e ait olduğunu ve hangi
gerekli komutu çalıştıracağını bilememesinden dolayı kodu derleyememesidir.
Ayrıca, bu şemaların URL gibi göründüğüne kapılarak belirli bir siteye işaret ettiğini düşünmeyelim. Örneğin:
http://schemas.microsoft.com/winfx/2006/xaml linkini tarayıcınızın adres bölümüne girdiğinizde
sayfanın bulunamadığı mesajı ile karşılaşırsınız. Aslında aynı C# dosyasında namespace'leri tanımladığımız gibi şemalar da birer
unique ifadelerdir
ve sınıf isimlerini belirli bir sırada tutmayı sağlarlar (Aynı isim, soyisim gibi). Şemalar URL (Uniform Resource
Locator)
(kaynak bulucu)
değil aslında birer
URI (Uniform Resource
Identifier)
(kaynak tanımlayıcısı)'dırlar.
5-6. satırda farklı URI'lere sahip
Phone ve
Shell için tanımlanan şemalar, Windows Phone 8 API'sini kurduktan sonra bilgisayarlarımıza
yüklenen
Microsoft.Phone CLR namespace'inin temel elemanlarıdırlar. İlk satırda da gördüğümüz gibi
<phone:PhoneApplicationPage ile
PhoneApplicationPage
sınıfının tanımlaması yapılmıştır. Bu sınıf diğer Windows Presentation Foundation (WPF) sınıfları ve Windows Store App sınıfları gibi
Windows.System.Controls.Page 'den türemiştir. Bu nedenle, 3 proje türünün (WPF, Store, Phone) birbiri ile paylaştığı birçok temel özellikleri
vardır. Bu yüzden eğer daha önceden WPF masaüstü uygulamaları ve Windows Store uygulamaları ile ilgilenmemişseniz veya bazı alanlarda eksiğiniz varsa
geriye dönüp kısa bir tekrar etmekte fayda var.
7-8. satırlarda tanımlanan şemalar sol taraftaki dizayn önizleme penceresinin görüntülenmesini sağlarlar. Bu şemalar sadece önizleme ile ilgili komutları
içerdiği için uygulamanın derlenmesi sırasında gereksiz yer kaplamamalıdırlar. 9'daki
mc:Ignorable="d" satırından sayesinde bu komutlar için derleme
yapılması engellenmiş olur.
10-12 satırlarda tanımlanan özellikler ile sayfa içerisinde kullanacağımız font ile ilgili belirlemeleri yapmış oluyoruz.
PhoneFontFamilyNormal gibi
kaynaklar halihazırda emülatörde varolan kaynaklardır. Phone uygulamalarında bu şekilde WPF'teki gibi
Binding mekanizması çok kullanılıyor.
13.satırda tanımlanan özellikler ile uygulamamızın çalışma esnasında ekranda duracağı konumu (yatay/düşey) belirtiyoruz.
SupportedOrientations ile
telefon yatay konuma alındığında uygulamanın da yatay moda geçmesi desteğini verebiliyoruz.
Orientation="Portrait" ile
soldaki pencerede,
tasarım emülatör'ünün yukarıdan aşağıya olacak şekilde durmasını sağlıyoruz.
14.satırda
SystemTray denilen ise, yukarıdaki şarj durum, saat, GPRS çekim gücü gibi bilgilerinin bulunduğu alanın, uygulamanın çalışması esnasında
görünüp görünmemesini sağlıyoruz.
Peki ya .xaml ve .xaml.cs dosyaları arasındaki ilişki?
Visual Studio'nun sağda,
Solution Explorer'da MainPage.xaml'ın sol tarafında bir üçgen şekli vardır. Bu şekile tıklayıp genişlettiğimizde ise
isimleri aynı fakat sadece sonu
.cs ile biten bir dosya ile karşılaşırız.
Bu dosyayı açtığımızda MainPage sınıfını ve üstelik
partial anahtar kelimesi ile tanımlandığını görebiliriz.
Bir diğer benzerlik de XAML dosyamızdaki 1-2 satırlarında tanımlanmıştır:
Bu şekilde iki dosyada da benzer tanımlamaların yapılmasının sebebi, derleyicinin
MainPage.xaml ve
MainPage.xaml.cs dosyalarını tek bir sınıf
haline getirmesi içindir. Bu iki dosya aslında bir elmanın iki yarısı gibidirler. MainPage.xaml.cs dosyasındaki, constructorda yer alan
InitializeComponent() fonksiyonu XAML dosyasının parse edilmesi esnasında tüm arayüz bileşenlerinin yüklenmesini sağlar. XAML dosyası da aynı C#
dosyası gibi bir
ara dil (intermediate language)'e çevrilir ve ikisi de tek bir sınıfın parçalar halinde kodlarını oluştururlar. Bu şekilde ayrımın
yapılmasıyla bir sınıfta oluşturduğumuz bileşeni diğer sınıfta kullanabiliriz ve böylece bu iki ayrı sınıfın birbiriyle haberleşmesini sağlarız. Örneğin
XAML dosyasında:
şeklinde tanımladığımız bir Button bileşeninin; en, boy, stil gibi diğer özelliklerini C# dosyasında ismini kullanarak değiştirebiliriz.
Peki ya XAML dosyasında bileşenler nasıl oluşturulacak?
Aslında her XAML dosyası özelleşmiş bir XML dosyasıdır. Bir elemanın içerisine diğer elemanları gömerek hiyerarşik bir yapı oluşturabiliriz:
<PhoneApplicationPage ...>
<Grid>
<TextBlock ... />
<Button ... />
</Grid>
</PhoneApplicationPage>
Burada
PhoneApplicationPage bileşeni bir
Grid içeriyor ve Grid bileşeni de
TextBlock ve
Button içeriyor. Daha detaylı
açıklayacak olursak, oluşturduğumuz her MainPage.xaml sayfası aslında birer
UserControl'dür. Buradaki UserControl'ün
Content değişkenine bir
Grid atanmış ve Grid'in
Children listesi ise TextBlock ve bir Button içermiştir. Burada <Grid> şeklinde ayrı bir tag olarak gösterdik ama
kullandığımız bileşene göre
embedded (gömülü) bir tarzda bileşenin
default içeriğinde değişiklikler yapabiliriz:
veya
örneğinde Button'ın Content özelliği default bir özelliktir.
Button’ın Content özelliğini atadık da oldu bitti mi şimdi?
Tabi ki bitmedi daha ne özellikler var. Mesela XAML dosyasındaki bileşenlerin özelliklerinin değiştirilmesi, bu işi C#'da yapmaya göre daha kolay ve kısa.
Örneğin Butonun arkaplan rengini değiştirmek için C#'da:
bu şekilde önce SolidColorBrush nesnesi oluşturup sonra da Colors enumerable'ındaki Blue'yu parametre olarak göndermemiz gerekiyor halbuki XAML tarafında:
üstteki Background kod parçasını eklememiz kafî gelecektir. Tabi her zaman yaptığımız işler bu kadar basit olmayabiliyor. Mesela
şeklinde bir buton tanımlayalım ve sonra sağdaki
Properties penceresine

gelip
Brush alanına tıklayarak, Background özelliğinin altındaki 3. kutucuğu seçerek, Button’ın
Background özellğinin türünü
LinearGradientBrush olarak değiştirelim. Sonra köşedeki renk seçim aracını kullanarak mavi renk ve tonlarını seçelim. Button'umuz önizleme penceresinde bu şekilde görünüyor
olmalı:
Visual Studio'nun da boş durmayıp bize bu kodları hazırladığı için ayrıca teşekkürler:
Eğer yukarıdaki kodları Properties penceresi kullanmadan hazırlayacak olsaydık. LinearGradientBrush oluşturup içerisindeki parametreleri iyice düşünerek,
tamamen doğru bir şekilde girmek zorunda kalırdık.
Dikkat edersek burada oluşan kod, öncekinde oluşturduğumuz gibi Background="Red" şeklinde değil. <Button.Background> gibi
<Control.Property> formuna
property element syntax denir.
Burada kullandığımız
Brush kelimesi ise, aynı resim fırçaları gibi boyamaya yarayan ve renkleri temsil eden birer nesnedir.
Linear olması ise
renk düzeylerinin yukarıdan aşağıya veya soldan sağa doğrusal bir şekilde değişiklik göstermesidir. Ben burada örnek olsun diye LinearGradientColor
kullandım fakat siz kendi geliştireceğiniz uygulamalarda bunu asla
yapmamanız gerekir. Çünkü, gradyanlı bir şekilde bileşenleri boyamak
Windows Phone 8 uygulamalarının estetiği için aykırıdır ve kullanıcıların da daha çok görünüme önem verdiği için bizim uygulamamızı kullanmak
isteyemeyebilirler. Fakat şimdilik kendi örneğimizde rahatça tüm bileşenlerle oynayabiliriz :)
GradientStop
özellikleri ise, LinearGradientBrush'ın sahip olduğu bir GradientStop collection’ının içerdiği renk aralıklarıdır. Fakat nedense kod kısmında bu renk
aralıklarını barındıran collection tanımlanmamış. Çünkü Visual Studio bizim için otomatik olarak kod satırlarını kısaltmıştır. Aslında kod şu şekilde
olmalıdır:
Farkettiğimiz gibi
<LinearGradientBrush.GradientStops> ve
<GradientStopCollection> elemanları koddan çıkarılmıştır. Bu kısa ve öz
olan kod satırları XAML parser'ın yetenekleri doğrultusunda oluşturulmuştur. GradientStops tanımlaması, LinearGradientBrush'ın ön tanımlı bir özelliğidir.
Aynı zamanda GradientStopCollection'ın bir türüdür ve GradientStopCollection'da
IList<T>'yi implement eder. Bu yüzden buradaki
T değeri
bir GradientStop nesnesine karşılık gelir. <LinearGradientBrush ../> etiketleri arasında kalan nesneler, GradientStopCollection'a çalışma zamanında
.Add() fonksiyonu gibi eklenir.
Uygulamamızdaki XAML kodunda, butona eklediğimiz
Click metodununun üstüne sağ tıklayıp çıkan menüde
Navigate to Event Handler'ı seçerek,
metodun C# koduna gidebiliriz.
Fonksiyonumuzda iki tane parametre var.
sender nesnesi o an için olayı çağıran bileşeni kullanmamızı sağlar (Örneğin şu anki bileşenimiz olan
Button gibi).
RoutedEventArgs e ise o olayla ilgili bilgilerin tutulduğu nesnedir.
RoutedEvent bir olayı görsel nesnelerin
bulunduğu ağaçta aşağıdan yukarı
(Tunnel) veya yukarıdan aşağı
(Bubble) bir şekilde iletmeyi sağlar. Örneğin:
| Bubble (Click olayı) ile
|
Button->StackPanel->Grid
|
| Tunnel (PreviewClick olayı) ile
|
Grid->StackPanel->Button
|
şeklinde ağacı dolaşabiliriz. RoutedEvent sayesinde, Click olayını tek bir bileşenin işlemesi yerine, ağaçtaki tüm parent/child'ların işlemesi sağlanır.
Eğer sadece tek bir bileşenin bu olayı işlemesini istiyorsak, bileşenin gerçekleştirdiği fonksiyonun içerisine
e.Handled = true; yazmamız
yeterlidir.
Bu kadar bilgiden sonra aşağıdaki kod satırını fonksiyonumuza ekleyelim
(sender as Button) ile aslında varolan sender objesi
primitive(ilkel) ve temel obje sınıfı olduğu için Button'a dönüştürmemiz gerekiyor (Aslında
içeriği alabilmek için Button'ın adını (myButton’ı) da kullanabilrdim ama sender'ın nasıl kullanıldığını göstermek için bu örneği verdim). Sonrasında
içeriğini yani "HelloWorld" yazısını alıp sonuna ünlem işareti ekledik.
F5'e basıp emülatörde nasıl çalıştığına bakalım.
Button'a tıkladığımızda telefonumuzun tema rengi yan statik
PhoneAccentBrush kaynağından dolayı kırmızı rengi aldı. PhoneAccentBrush da ne diyenler
olabilir fakat o da başka bir yazının konusu olsun. Görüşmek dileğiyle :)
Kaynaklar:
StackoverFlow
MSDN