Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!  
Daron Yöndem
bir yazılımcının tasarıları...
 Wednesday, July 21, 2010

Silverlight ile OOB (Out-Of-Browser) modunda uygulamalar geliştirirken bir diğer hissedilebilen ihtiyaç da bu uygulamaları bazen ayrı bir şekilde dağıtabilmek oluyor. Normal şartlarda bir OOB uygulaması ancak Silverlight uygulamasının webde istemcide açılması aracılığı ile yüklenebiliyor. Fakat bunun haricinde isterseniz bu yükleme işlemini bir script ile başlatma şansınız da olabilir. Böylece söz konusu script bir SETUP paketine konduğunda rahatlıkla Silverlight OOB uygulamasını tek başına CD/DVD gibi bir medyada dağıtılabilir hale getirebilirsiniz.

[Silent installation script]

"%ProgramFiles%\Microsoft Silverlight\sllauncher.exe"
/install:"SLDosya.xap"
/origin:"http://www.ornek.com/ClientBin/SLDosya.xap"
/shortcut:desktop+startmenu /overwrite

Yukarıda gördüğünüz komutu çalıştırmanız haline yükleme işlemi hemen başlayacaktır. Burada önemli olan birkaç detay var, birincisi 64-bit yüklü sistemlerde ProgramFiles klasörünün adının değiştiğini unutmayın :) Bu nedenle olası bir SETUP paketi hazırlarken farklı ihtimalleri kontrol etmeniz gerekecektir. İkinci detay ise komuta gönderdiğimiz parametrelerin kendisi. İlk parametremiz olan install doğrudan OOB modunda yüklemek istediğimiz SL uygulamasının dosyasını hedefliyor. Dosya lokal dosya sistemine bulunmalı. İkinci parametre olan origin parametresi ise dosyanın webden güncellenebileceği adresi belirtiyor. Daha önce de belirttiğim gibi normalde bu yükleme işlemi webden yapılıyordu ve o senaryoda webdeki XAP dosyasının adresi belli olduğu için runtime tarafından kenara kaydedilerek sürekli webde yeni bir sürümün bulunup bulunmadığı kontrol edilebiliyor varsa yenisi hemen istemciye indirilebiliyordu. Oysa şu anda biz bir anlamda offline yükleme yaptığımız için dosyanın webdeki güncelleme noktasını elle belirtmemiz gerekiyor. Böylece aynı webden yüklenmiş gibi update mekanizması çalışmaya devam edecektir.

Son parametremiz ise shortcut parametresi. Yükleme esnasından nerelere kısayollar konulmasını istiyorsanız onları da bu parametreye vererek ilerleyebilirsiniz. Son olarak overwrite parametresini de verirseniz eğer uygulama daha önceden yüklenmiş ise yenisi üzerine yazılacaktır. Ek olarak eğer uygulamayı yükledikten sonra otomatik olarak anında çalıştırmak da istiyorsanız bu sefer de aşağıda komutu kullanabilirsiniz.

[Otomatik çalıştırma scripti]

"%ProgramFiles%\Microsoft Silverlight\sllauncher.exe"
/emulate:"SLOrnek.xap"
/origin:"http://www.ornek.com/SLOrnek.xap"
/overwrite

Unutmamak gerek ki tüm bu işlemlerde sizin uygulamanızla iligli ayırt edici olan bir nevi GUID özelliği taşıyan parametre aslında origin parametresidir. Yani sllauncher.exe tüm uygulamaları origin parametresi üzerinden tanır ve ayırt eder. O nedenle bir uygulamayı sistemden kaldırmak için kullanacağımız aşağıdaki scriptte de sadece origin parametresini vermemiz uygulamanın sistemden silinmesi için yeterlidir.

[Uninstall scripti]

"%ProgramFiles%\Microsoft Silverlight\sllauncher.exe"
/uninstall
/origin:http://www.ornek.com/SLOrnek.xap

Hepinize kolay gelsin ;)

Wednesday, July 21, 2010 9:40:25 AM (GTB Standard Time, UTC+02:00)  #    Comments [1]   Silverlight 4  | 
 Tuesday, July 20, 2010

Sanırım aradan epey zaman geçti fakat :) geçenlerde misafir olarak bulunduğum bir şirkette aşağıdaki ipucunu paylaştığımda "Neden bloga yazmıyorsunuz bunları?" tepkisini alınca :) aklımda kenara not almıştım. "Bunu bloga yazmam lazım" şeklinde :) ve zamanı geldi. Biliyorsunuz Silverlight'ın bir OutOfBrowser modu söz konusu ve özellikle "Elevated Trust"ın da gelmesi ile epey popüler olmaya başladı bu özellik. Peki bu şekilde OOB modunda çalışan uygulamalar geliştirirken uygulamamızı nasıl debug edeceğiz? Sonuçta F5'e bastığımızda projemiz hem bir web sunucu üzerinden çalıştırılıyor ve uygulama windows modunda açılamıyor.

Visual Studio 2010 ile beraber bu soruna da bir çözüm geldi. Artık Silverlight projenizi OOB moduna geçebilecek şekilde ayarladıktan sonra Silverlight projenize sağ tıklayıp "Properties" komutunu verdiğinizde "Debug" tabında özel bir ayar bulabilirsiniz.

Out Of Browser modunda debug seçeneği.
Out Of Browser modunda debug seçeneği.

Yukarıdaki ekran görüntüsünde de gördüğünüz üzere Debug ayarlarında eğer "Out-of-browser application" seçeneğini işaretlerseniz artık Visual Studio 2010 içerisinde F5'e bastığınızda Silverlight uygulamanız doğrudan Desktop uygulaması gibi açılacaktır ve rahatlıkla her tür debugging işlemini yapabileceksiniz.

Hepinize kolay gelsin ;)

Tuesday, July 20, 2010 9:10:36 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 3.0 | Silverlight 4 | Visual Studio 2010  | 
 Monday, July 19, 2010

Yeni bir Silverlight projesi yaratırken çoğu zaman yanında bir de ASP.NET sitesi alırız. Böylece veritabanı erişimi vs gibi işlemleri ASP.NET tarafında yapabilir ve rahatlıkla Silverlight uygulamasını sitemize entegre etmiş oluruz. Bunun üzerine ek olarak Silverlight debugging özelliklerini de sitemizi debug ederken kullanabiliriz. Tüm bunlar güzel, hoş ama ya zaten elimizde bir site varsa ve buna Silverlight projesi eklemek istersek? Bu noktada da sorun yok çünkü Visual Studio 2010 içerisinde "File / Add New Project" diyerek yeni bir SL projesi yarattığınızda karşınıza söz konusu projeyi solution içerisindeki hangi asp.net projesi ile linklemek istediğiniz soran bir pencere gelecektir. Bu penceredeki ayarlarla yine yukarıda saydığımız tüm kolaylıklardan faydalanabilirsiniz.

Esas sorun elde var olan ve birbirinden bağımsız Silverlight projeleri ile ASP.NET projeleri birleştirirken ortaya çıkıyor. Bir solution içerisine "File / Add Existing Project" diyerek hepsini ekleseniz de maalesef entegrasyonla ilgili hiçbir işlem gerçekleşmiyor ve size hiçbirşey sorulmuyor. O nedenle F5'e bastığınızda ne SL projesi build oluyor ne XAP web sitesine kopyalanıyor ne de SL Debugging özellikleri aktif oluyor. Bu sıkıntılı durumu çözmek için Visual Studio 2010 içerisinde özel bir ayar söz konusu ;)

Visual Studio'da Solution Explorer içerisinde Silverlight uygulamanızı linklemek istediğiniz web uygulamasına sağ tıklayarak "Properties" / "Property Pages" komutunu verdikten sonra karşınıza gelecek ekranda "Silverlight Applications" diye bir sekme göreceksiniz. İşte tam da bu ekranda artık ister yeni bir SL uygulaması yaratabilir ister solution içerisindeki başka bir SL projesini ASP.NET sitesi ile eşleştirebilirsiniz.

Var olan SL projesi ile ASP.NET'i birbirine linklemenin yolu.
Var olan SL projesi ile ASP.NET'i birbirine linklemenin yolu.

Eşleştirme işlemi esnasında XAP'ın kopyalanacağı klasörü belirtebilir aynı anda eğer istiyorsanız sizin için otomatik bir test HTML sayfası da yaratılmasını sağlayabilirsiniz. Son olarak "Enable SL Debugging" seçeneği de işaretli tutmayı unutmayın ki ASP.NET projenizi debug ederken SL kısımlarındaki hataları da rahatlıkla inceleyebilin.

Hepinize kolay gelsin ;)

Monday, July 19, 2010 9:14:59 AM (GTB Standard Time, UTC+02:00)  #    Comments [2]   Silverlight 4 | Visual Studio 2010  | 
 Thursday, May 20, 2010

Ürdün :) Son üç gündür Ürdün'deydim! Microsoft Ürdün ofisi için iş ortaklarına ve sektördeki yazılım geliştiren kurumlara özel bir seminer serisi düzenledik. Oturumlar boyunca Silverlight, WPF, Multitouch, Windows 7 Features, Sensor and Location API Development, .NET 4 Yenilikleri gibi konulara değindim. Gerçekten güzel geçen üç gün içerisinde maalesef pek Ürdün'ü gezme şansım olmadı. Fakat önümüzdeki hafta yine Ürdün'de yapacağımız laboratuar çalışmaları ve bir sonraki hafta da müşteri ziyaretleri düşünülürse :) Kesin arada bir fırsat bulacağımdan eminim.

Microsoft Ürdün Seminerlerim
Microsoft Ürdün Seminerlerim

Etkinlik boyunca Ürdün'den bir de Türk kardeşimize rastladım. Bu gibi etkinlikler halka açık olmadığı için genelde blogumda duyurmuyorum. Türkiye'de de bolca yapıldığını itiraf etmem gerek. Özellikle BizSpark, WebSiteSpark gibi programların üyeleri yazılım şirketleri için sıkı seminerler ve eğitim programları Türkiye'de de düzenleniyor. Fakat bahsettiğim gibi bu etkinlikler dışarıya kapalı olduğu için duyurmayı anlamlı bulmuyorum. Bazılarının kayıtlarını SeminerTV'de paylaştım o kadar :) İtiraf etmek gerekirse artık etkinliklerden sonra bloga da post atmayı unutur oldum, hatta bu konuda sitem bile alıyorum "Neden bizi yazmadınız" diye :) Atladığım her etkinliğin katılımcılarından özür dilerim bu vesile ile.

Neyse konuyu toparlayalım :) Eğer Ürdün'deyseniz ve bu yazıyı okuyorsanız :) ve tabi ki yazılımla ilgileniyorsanız bana bir mail atın beraber birer çay içelim ;)

Görüşmek üzere!

Thursday, May 20, 2010 7:40:45 AM (GTB Standard Time, UTC+02:00)  #    Comments [9]   .NET Framework 4.0 | Expression Studio | MultiTouch | Seminer | Silverlight 4 | Visual Studio 2010 | Windows 7 | Windows Phone 7 | WPF  | 
 Thursday, May 13, 2010

Şu ana kadar bildiklerimize dayanarak Windows Phone 7'nin multitasking desteklemeyeceğini rahatlıkla söyleyebiliriz. Bu durum birer yazılım geliştirici olarak çok işimize gelmese de aslında son kullanıcı açısından bunun birçok faydası var. Cihazların pil ömründen tutun performansına kadar çoğu noktada multitasking aslında cebimizde bu minik cihazların kaldıramayacağı bir yük gibi duruyor. Son kullanıcı tarafından baktığımızda sadece kabaca bu duruma iPhone ile herkes alışkın. İşin bir diğer komik yanı ise aslında hiçbir son kullanıcının pek de bu durumu önemsemiyor olması. Yani biz yazılımcılar kadar konuya teknik açıdan bakıp endişelenen pek yok gibi :)

Bir son kullanıcı için önemli olan aslında çalıştırdığı programın arkada çalışıp çalışmadığı bilmekten öte istediği işin yapılıp yapılmadığını veya daha sık karşılaştığımız senaryolarda herhangi bir işin takibinin yapılıp yapılmadığını bilmek. Daha somut bir örnek vermek gerekirse varsayalım ki bir mail istemcisi kullanıyorsunuz. Normalde bilgisayarımızda mail programını açık tutmamızın nedeni mail geldiğinde haberdar olmaktır. Oysa bunun için koca mail programının açık olmasına gerçekten gerek var mı? Yani daha ufak bir yapı arkada mail geldiğinde haberdar olsa da bize ufak bir uyarı mesajı verse? Sonra gerekiyorsa ben mail programını çalıştırıp istediğimi yapsam olmaz mı? İşte Windows Phone 7 içerisinde yer alan PushNotification sistemi de tam olarak bunu çözüyor.

Olayın işleyişine bir göz atalım...

Push mesajlarının gönderiminde toplam üç farklı kimlik bulunuyor diyebiliriz. Bunlardan biri mesajı dinlemede olan telefon, diğeri mesajı gönderen servis, bir diğeri ise iki servisin birbirine ulaşabilmesini sağlayan bir anlamda router görevi gören Microsoft servisi. Her telefon dinleme moduna geçerken bir kanal ismi tanımlayarak kendini "Microsoft Push Notification Service" üzerinde tanımlıyor.

Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.
Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.

Yukarıdaki şemada da görebileceğiniz üzere telefon kendi dinleme kanal adı ile servise başvurarak bir adres talep ediyor. Bu adres farklı servislerin telefona push notification gönderirken kullanacakları adres olacak. Böylece rahatlıkla bu adrese sahip her tür yazılım bu adres üzerinden notification gönderebilecek. Söz konusu notification'lar uygulamanız kapalı olsa da işletim sistemi tarafından dinleneceği için uyarılar her zaman kullanıcılara gösterilebilecek. Tabi bu sistemin çalışması için daha önce de bahsettiğimiz üzere bizim de push notificationları sağlayacak bir servise ihtiyacımız var ve bu servisin de telefonun adresine sahip olması gerekiyor.

Push Notification telefona gönderiliyor.
Push Notification telefona gönderiliyor.

İlk aşamada telefon bizim yazacağımız bir servise kendi adresini aktarıyor. Böylece servis artık telefona ulaşabileceği adresi bildiğine göre Push Notification yollmaya hazır. Aslında telefon verdiği adres tam olarak kendi adresi de değil :) Unutmayın bu adres Microsoft Push Notification Service'in verdiği adres. Telefon Microsoft Push Notification Service'den aldığı adresi bizim servise veriyor ve artık bizim servis de bu adrese istediği mesajı gönderiyor. Gönderilen bu mesaj özünde yine Microsoft Push Notification Service'e gidiyor ve Microsoft Push Notification Service'de mesajı telefona iletiyor. Böylece MSPush Notification Service ile cihaz bir Socket bağlantısına sahipken bizim servisimiz sadece istediğinde MS Push Notification Service ile bağlantı kurarak mesaj gönderebiliyor.

Peki nasıl yapacağız bu işleri?

Biz kendi servisimizi temsil etmek üzere bir WPF uygulaması yazalım. Böylece WPF uygulaması kendi içerisinden telefona PUSH mesaj yollayabilir olsun. Uygulamamızın içerisinde telefondan gelecek adres bilgisini alabilecek bir servis olması gerek. Bu servise gelen adrese sonrasında gönderim yaparak telefonu PUSH data yollamış olacağız. 

[VB]

Public Class Service1

    Implements IService1

 

    Public Sub SetURL(ByVal URL As System.Uri) Implements IService1.SetURL

        MainWindow.URL = URL.AbsoluteUri.ToString()

    End Sub

End Class

Gördüğünüz gibi servisimiz epey basit. Tek yaptığı adresi alıp WPF uygulamamızın içerisinde başka bir sınıfta tanımlı shared bir obeye atamak. Herhangi bir sorunla karşılaşmamak adına servisi basicHttpBinding olarak ayarlamanızı tavsiye ederim. Servisin default gelen design adresini kullanarak WP7 uygulamamıza referans olarak ekleyebiliriz hemen. WPF uygulamasında App.Config içerisinde http://localhost:8732/Design_Time_Addresses/WpfApplication1/Service1/ gibi bir adres göreceksiniz. Uygulamamız örnek amaçlı olduğu için doğrudan bu adresi kullanarak WP7 uygulamanıza service reference ekleyebilirsinzi. Tabi onun öncesinde bu servisin host edilmesini de sağlamamız gerek.

[VB]

    Public Shared URL As String

 

    Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim SHost As New ServiceHost(GetType(Service1))

        SHost.Open()

    End Sub

İşte bu kadar basit. Uygulamamız açıldığı anda bu servisi host edecek ve böylece bizim WP7 uygulaması da bunu referans alıp kullanabilecek. İsterseniz şimdi de gelin WP7 uygulaması tarafındaki PushNotificationService tanımına bakıp Microsoft Push Notification Service üzerinden adres alıp bizim WPF uygulamasına göndermeye çalışalım.

[C#]

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            var Kanal = new HttpNotificationChannel("UygulamaKanali15");

            Kanal.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(Kanal_ChannelUriUpdated);

            Kanal.Open();

            Kanal.BindToShellNotification();

        }

Kodumuzda yarattığımız HttpNotificationChannel sınıfı Microsoft.Phone.Notification assembly'si altında olduğu için söz konusu DLL'i projeye referans olarak eklemeyi unutmayın. Sonrasında HttpNotificationChannel nesnemizi yaratarak kendi tanımladığımız bir de kanal ismi veriyoruz. Nesnemize ait ChannelUriUpdated event'ı Microsoft Push Notification Service'den cihazın adresi geldiğinde çalışıyor. Özünde biz şu anda hem Push Listener tanımlayıp bunun için Microsoft Push Notification Service'den adres isteyerek elimizdeki Push Notification Service'i de BindToShellNotification ile işletim sistemine aktarıyoruz. Adres geldiğinde söz konusu adresi bizim WPF uygulamasındaki servise aktaracağız.

[C#]

        ServiceReference1.Service1Client Servis = new ServiceReference1.Service1Client();

 

        void Kanal_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)

        {

            Servis.SetURLAsync(e.ChannelUri);

        }

WPF uygulamamızdaki servisi reference aldığımıza göre içerisindeki SetURL metodunu kullanarak ChannelUriUpdated eventinden gelen adresi gönderebiliriz. Böylece WP7 uygulamamız kendi adresini alıp bizim servise göndermiş oldu. Bir sonraki adımda bizim bu adrese yani Microsoft Push Notification Services'a bir mesaj yollamamız gerekiyor ki mesaj telefona iletilsin ve kullanıcıya gösterilsin. Bu nedenle geçiyoruz yine WPF uygulamamıza.

[VB]

        Dim MesajXML = <?xml version="1.0" encoding="utf-8"?>

                       <wp:PushNotification xmlns:wp="WindowsPhonePushNotification">

                           <wp:Toast>

                               <wp:Text1>Mesaj1</wp:Text1>

                               <wp:Text2>Mesaj2</wp:Text2>

                           </wp:Toast>

                       </wp:PushNotification>

 

        Dim Mesaj As String = "X-WindowsPhone-Target: toast" & vbCrLf & vbCrLf & MesajXML.ToString()

Yukarıdaki gördüğünüz XML paketi Microsoft Notification Service'e göndermemiz gereken paket. Bu paketin otomatik hazırlanması ile ilgili bir helper sınıfı eminim ki yakında yayınlanacaktır. Fakat şimdilik elle yapmamız gerekiyor. Paketin içerisinde iki adet String data var. Bu dataları istediğiniz gibi değiştirebilirsiniz. Son olarka hazırladığımız bu paketi daha önce servisimize iletilmiş olan adrese gönderiyoruz.

[VB]

        Dim Gonder As HttpWebRequest = WebRequest.Create(URL)

        Gonder.Method = "POST"

        Gonder.Headers = New WebHeaderCollection()

        Gonder.ContentType = "text/xml"

        Gonder.Headers.Add("X-NotificationClass", "2")

 

        Dim ByteArr = New UTF8Encoding().GetBytes(Mesaj)

        Gonder.ContentLength = ByteArr.Length

        Dim GStream = Gonder.GetRequestStream

        GStream.Write(ByteArr, 0, ByteArr.Length)

ToastNotificaton olarak adlandırılan ve telefonun ekranının üst kısmında bir uyarı olarak çıkan bu mesajlar için üç farklı aciliyet seviyesi belirleyebiliyorsunuz. Yukarıdaki kod içerisinde 2 değeri anında teslimat yapılması gerektiğini belirtliyor. 12 ve 22 gibi değer vererek mesajınızın ToastNotification'lar harici farklı Push Notification mesajları arasında da nasıl önceliklendirilebileceğini belirtebiliyorsunuz. Eh artık herşey hazır. WPF uygulamamızı çalıştırıp WP7 uygulamamızı da başlatabiliriz. WP7 uygulaması ilk olarak Microsoft Notification Services'a bağlanıp kendine bir adres yarattıracak. Sonrasında bu adresi bizim WPF uygulamamıza verecek. WPF uygulamamız da artık istediği zaman bu adres mesaj gönderebilecek. Burada önemli olan nokta telefonda uygulamanız kapalı olsa da mesaj işletim sistemi tarafından alınarak kullanıcıya gösterilebilecek.

ToastNotification sahnede.
ToastNotification sahnede.

Hepinize kolay gelsin.

Thursday, May 13, 2010 4:05:08 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 
 Wednesday, May 12, 2010

GPS sensörleri gün geçtikçe her yerde karşımıza çıkıyor. Kişisel olarak konuşmam gerekirse bir cep telefonu satın alırken GPS sensörüne sahip olması benim için satın alma kararımda çok önemli bir kriter. Özellikle harita uygulamalarına özgüymüş gibi düşünsek de aslında çoğu uygulamanın farklı şekilde kullanıcızı fiziksel konumuna ait bilgiyi kullanma şansı olabilir. En basit örnek olarak bir çeviri uygulaması düşünün İngilizceden Türkçe'ye çeviri yapıyor. Bu uygulama benim Fransa'da olduğumu anlasa ve hemen Fransızca'dan çeviri moduna geçse hoş olmaz mı? Tabi ki tüm bunların ayarlanabilir olması şart fakat bu tarz işlevsellikler uygulamalara eklenebilmesi için en önemli nokta uygulama geliştiriciler için donanımdan bağımsız kod yazma olanağı yaratmak.

Windows Phone 7 cihazlarında GPS sensörü bulunması şart. O nedenle uygulama geliştirirken her şekilde bir GPS sensörüne sahip olduğunuzu düşünebilirsiniz. Diğer yandan özünde bir kullanıcının dünya üzerindeki yerini tespit ederken ne kadar detaya ihtiyacınız olduğuna da karar vermelisiniz. Eğer benim bir önceki örneğimde bahsettiğim gibi sadece hangi ülkede bulunduğu sizin için önemli ise belki de bu bilgiyi doğrudan telefonun sinyal aldığı GSM servisi üzerinden alabilirsiniz. Eğer çok ciddi detaya ihtiyacınız varsa tabi ki GPS sensörünü çalıştırmanız gerekecektir. Hatta GPS konusunda da uydu pozisyonları ile ilgili ek verilerin indirilmesi için Wi-Fi veya 3G üzerinden internete çıkıp global veritabanlarından veri almanız gerekebilir. Tüm bunların hepsini Windows Phone 7 bizim yerimize yapıyor ve en önemlisi ise bize edinmek istediğimiz verinin ne kadar detaylı olması gerektiğine dair karar verme şansı tanıyor. Böylece belki de çok detaya ihtiyacınız olmayan bir senaryoda GPS sensörünü çalıştırmadan (kaynak tüketmeden) ilerleyebiliriz.

Başlayalım...

WP7'de Location API kullanabilmek için projenize ilk aşamada System.Device.Location DLL'ini referans almanız gerekiyor. Sonrasında aşağıdaki gibi uygulama ekranımızı tasarlayıp sensörümüze ulaşmaya başlayabiliriz.

[XAML]

<Grid x:Name="ContentGrid" Grid.Row="1">

  <Button Content="Button" Height="50" HorizontalAlignment="Left" Margin="116,23,0,0" Name="button1" VerticalAlignment="Top" Width="252" Click="button1_Click" />

  <TextBlock Height="57" HorizontalAlignment="Left" Margin="167,139,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="144" />

  <TextBlock Height="57" HorizontalAlignment="Left" Margin="154,201,0,0" Name="textBlock2" Text="TextBlock" VerticalAlignment="Top" Width="144" />

</Grid>

Her zamanki gibi demo amaçlı olarak uygulama ekranına iki TextBlock ve bir de Button koyduk. Amacımız düğmeye basıldığında sensöre ulaşıp aldığımız koordinat bilgilerini de iki TextBlock üzerinde göstermek.

[C#]

    private void button1_Click(object sender, RoutedEventArgs e)

    {

        GeoCoordinateWatcher Pozisyon = new GeoCoordinateWatcher(GeoPositionAccuracy.High);

        Pozisyon.MovementThreshold = 15;

        Pozisyon.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(Pozisyon_PositionChanged);

        Pozisyon.Start();

    }

Uygulama içerisindeki düğmeye tıklandığı anda yeni bir GeoCoordinateWatcher nesnesi yaratıyoruz. Constructor'a bir parametre ile beraber gittiğimiz dikkatinizi çekmiştir. İşte buradaki parametre bizim istediğimiz lokasyon bilgisinin hassasiyeti ile ilgili. Eğer GPS sensörü kullanılsın istiyorsanız High, yok sadece GSM üzerinden lokasyon alınsın istiyorsanız Low seçeneklerini kullanabilirsiniz. İkinci adımda MovementThreshold adında ek bir parametremiz daha var. Malum GPS cihazları (özellikle antensiz ve telefon içerisinde olanlar) çok hassas cihazlar ve ufak hatalar yapabiliyorlar. Örneğin siz sabit dursanız da sizi hareket ediyormuş gibi gösterebilirler. Bunu kısmen engellemek için bir "paraziti engelleme" parametresi belirliyoruz :) Aslında bu parametre ile belirli bir miktarın altındaki koordinat değişikliklerin raporlanmamasını sağlamış oluyoruz. Böylece gerçeken bizim "umursadığımız" bir değişiklik olduğunda bize rapor geliyor.

Bir sonraki adımda GPS sensöründen yeni veri geldiğinde haberdar olmak için kullanacağımız event listener'ımızı GeoCoordinateWatcher'ın PositionChanged eventine bağlıyoruz. Son olarak da bilgi alma işlemini yani sensörü dinleme işlemini başlatıyoruz.

[C#]

    void Pozisyon_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)

    {

        Dispatcher.BeginInvoke(() => Degisti(e));

    }

Pozisyon değişikliğini dinleyen listener'ımız beraberinde argümanı ile geliyor ve söz konusu argüman içerisinde bizim istediğimiz tüm bilgiler mevcut. Diğer yandan bu event başka bir thread tarafından çalıştırıldığı için yine UIThread'i bilgi aktarmak için Dispatcher üzerinden ayrı bir metod çağırıyoruz.

[C#]

    void Degisti(GeoPositionChangedEventArgs<GeoCoordinate> e)

    {

        textBlock1.Text = e.Position.Location.Latitude.ToString();

        textBlock2.Text = e.Position.Location.Longitude.ToString();

    }

Argümanımızı artık UIThread'e kadar aldık. Geriye eldeki parametreleri ekrana yazmak kaldı. Tabi siz farklı uygulamalarda bu parametreleri farklı şekillerde kullanabilirsiniz. Kötü haber ise MIX ile beraber gelen emülatörün GPS simülasyonu yapamaması. O nedenle bu gibi uygulamalar geliştirirken kendi sallama değerlerinizi yaratan bir sınıf kullanmanız çok daha mantıklı olabilir. Son noktada da gördüğünüz üzere Location implementasyonu rahatlıkla yapılabilir.

Hepinize kolay gelsin.

Wednesday, May 12, 2010 1:44:48 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 
 Tuesday, May 11, 2010

Cep telefonlarının en önemli parçalarından biri de artık Accelerometer'lar. Telefonu farklı yönlenere çevirdiğimizde durumu algılayan donanım parçasından bahsediyorum :) Aslında bu donanım son dönemde cep telefonlarından çıkıp bilgisayarlarımıza kadar geldi hatta bu konuda Windows 7 ile beraber "Sensor and Location API" adında yeni bir API serisi bile var. Tabi Windows Phone 7 için uygulama geliştirirken de doğal olarak cihazlardaki Accelerometer'a ulaşmamız gerekecek. Merak edenler için özellikle belirtiyim; üzerinde WP7 bulunan her telefonun bir Accelerometer içermesi Microsoft tarafından şart koşuluyor. O nedenle uygulamalarınızı kodlarken rahat olabilirsiniz, her halükarda bir Accelerometer sahibi olacaksınız.

İlk olarak gelin yeni yaratacağımız bir WP7 uygulamasına bir düğme ve üç tane de TextBlock koyalım. Düğmeye basıldığı anda Accelerometer sensörüne bağlantıyı kuracağız sonrasında da sensörden yeni veri geldikçe X, Y ve Z koordinatlarını ayrı ayrı TextBlock'larda göstereceğiz.

[XAML]

<Grid x:Name="ContentGrid" Grid.Row="1">

  <Button Content="Button" Height="50" HorizontalAlignment="Left" Margin="116,23,0,0" Name="button1" VerticalAlignment="Top" Width="252" Click="button1_Click" />

  <TextBlock Height="57" HorizontalAlignment="Left" Margin="167,139,0,0" Name="textBlock1" Text="TextBlock" VerticalAlignment="Top" Width="144" />

  <TextBlock Height="57" HorizontalAlignment="Left" Margin="154,201,0,0" Name="textBlock2" Text="TextBlock" VerticalAlignment="Top" Width="144" />

  <TextBlock Height="57" HorizontalAlignment="Left" Margin="137,250,0,0" Name="textBlock3" Text="TextBlock" VerticalAlignment="Top" Width="144" />

</Grid>

Tasarım kısmını kabaca bitirdiğimize göre sıra geldi Accelerometer nesnemizi yakalamaya. Malum telefonlarda bir Accelerometer şart olsa da sadece bir tane olması gerektiğine dair herhangi bir kural yok. O nedenle eğer isterseniz sistemdeki tüm Accelerometer'ların bir listesini Microsoft.Devices.Sensors.AccelerometerSensor listesinden alabilirsiniz. Tabi tüm bunları yapabilmeniz için projenize Microsoft.Devices.Sensors assembly'sini referans olarak da eklemiş olmanız gerekiyor.

Eğer tüm liste sizi ilgilendirmiyorsa ve bir anlamda esas sensörü yani varsayılan Accelerometer'ı almak istiyorsanız hızlıca Microsoft.Devices.Sensors.AccelerometerSensor.Default diyebilirsiniz.

[C#]

    AccelerometerSensor accelerometer;

 

    private void button1_Click(object sender, RoutedEventArgs e)

    {

        accelerometer = AccelerometerSensor.Default;

        accelerometer.ReadingChanged += new EventHandler<AccelerometerReadingAsyncEventArgs>(accelerometer_ReadingChanged);

        accelerometer.Start();

    }

Kod içerisinde de görebileceğiniz gibi uygulamamızdaki düğmeye basıldığı anda sistemdeki varsayılan Accelerometer'ı hemen daha önce tanımladığımız AccelerometerSensor tipindeki bir değişkene aktarıyoruz. Özünde bunu yapmamızın tek bir nedeni. Sensörü dinleme işlemini başlatmak için Start ve bitirmek için de Stop metodlarını kullanabiliyorsunuz. Malum sensöre ileride ulaşıp durdurabilmek için global bir değişken tanımlamak en mantıklısı. Bunun haricinde unutmamamız gereken birşey daha var; o da sensörün ReadingChanged event'ine bir listener ataçlamak. Böylece sensörden yeni data geldiği anda haberdar olabileceğiz.

[C#]

    void accelerometer_ReadingChanged(object sender, AccelerometerReadingAsyncEventArgs e)

    {

        Dispatcher.BeginInvoke(() => Degisti(e));

    }

 

    void Degisti(AccelerometerReadingAsyncEventArgs e)

    {

        textBlock1.Text = e.Value.Value.X.ToString();

        textBlock2.Text = e.Value.Value.Y.ToString();

        textBlock3.Text = e.Value.Value.Z.ToString();

    }

ReadingChanged eventı başka thread tarafından çalıştırıldığı için doğrudan UIThread'e ulaşamıyoruz. Bu nedenle Dispathcher üzerinden metodumuzu çalıştırmamız gerek ki UIThread'de işlem yapabilelim. Tüm bu süreçte bizim için değerli olan datayı taşıyan ise ReadingChanged'e gelen argüman parametresi. Söz konusu parametreyi doğrudan UIThread'deki metodumuza da yolluyoruz ki değerleri alıp ekrana yazabilsin. Son olarak Degisti adındaki metodun içerisinde X, Y ve Z değerlerinin nasıl alınabildiğini de görebiliyorsunuz.

Artık elimizde sensörün o an için bize gönderdiği koordinat bilgisi var. Geriye kalan bu bilgilere dayanarak uygulama içerisinde farklı birşeyler yapmak. Tabi bu noktadan sonrası için makalemie devam edemeyeceğiz :) Çünkü özünde minik ama kötü bir haberim var. Şu anda MIX ile yayınlanan Windows Phone 7 CTP'sindeki simülatör sensör desteğine sahip değil :( O nedenle bu yazdığımız kodların hiçbirini test etme veya uygulama geliştirme şansımız olmuyor. Yine de şöyle bir bakış atmış ve olayın nihai manzarada da ne kadar kolay olabileceğine dair fikir edinmiş olduk.

Hepinize kolay gelsin.

Tuesday, May 11, 2010 7:45:36 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 
 Monday, May 10, 2010

Bugün neredeyse her cep telefonunda bir Accelerometer mevcut. Böylece en basit işlevsellik olarak telefonumuzu yana çevirdiğimizde algılamasını ve ekranı da ona göre toparlamasını isteyebiliriz. İtiraf etmek gerekirse zaten Accelerometer sahibi olup da bu işi yapmayan telefon kalmadı gibi :) Diğer yandan önemli olan bizim uygulamalarımızda bu durumu algılayıp uygun tepkiler verebilmemiz. Bunun için Windows Phone 7 üzerinde uygulama geliştirirken de kullanabileceimiz API'ler mevcut. İşte bu makalemizde bu API'lere göz atarak basit bir resim gösteren uygulama yazacağız.

[XAML]

<Grid x:Name="ContentGrid" Grid.Row="1">

    <Image HorizontalAlignment="Stretch" Name="image1"

          Stretch="Uniform" VerticalAlignment="Stretch"

          Source="/WindowsPhoneApplication5;component/Images/Koala.jpg" />

</Grid>

Yukarıda gördüğünüz kod ile ekrana bir Image nesnesi koyarak projemize eklediğimiz bir resmi göstermesini sağlıyoruz. Bu esnada Image nesnesinin her tarafa genişleyebilmesi için tüm Alignment özellikleri Stretch olarak ayarlanmış durumda fakat diğer yandan da resmin en boy oranı bozulmadan büyütülmesi için Stretch özelliği de Uniform olarak ayarlanmış durumda. Peki bu şekli ile uygulamamızı çalıştırdığımızda neler oluyor?

Farklı pozisyonlarda uygulamamız.
Farklı pozisyonlarda uygulamamız.

Eh herşey süper gibi duruyor. Resmimiz her şekilde kendine kalan alanda en büyük şekilde gözükmeye çalışıyor. Fakat genelde kullanıcıların telefonu yana çevirmiş olarak kullanmadıklarını :) ve eğer yana çeviriyorlarsa büyük ihtimal resmi ekrana yayıp daha geniş görmek istediklerini düşünebilir miyiz? Kesinlikle :) İşte bu durumda bizim kullanıcının telefonu çevirdiğini anlamamız, hangi tarafa çevirdiğinizi öğrenmemiz ve ona göre ekranı tekrar toparlamamız gerekecek. Hadi bakalım, başlayalım.

[C#]

        public MainPage()

        {

            InitializeComponent();

 

            SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;

 

            this.OrientationChanging += new EventHandler<OrientationChangedEventArgs>(MainPage_OrientationChanging);

        }

 

        void MainPage_OrientationChanging(object sender, OrientationChangedEventArgs e)

        {

            if (e.Orientation == PageOrientation.LandscapeLeft ||e.Orientation == PageOrientation.LandscapeRight )

            {

                TitleGrid.Visibility = System.Windows.Visibility.Collapsed;

                Grid.SetRow(ContentGrid, 0);

                Grid.SetRowSpan(ContentGrid, 2);

            }

            else

            {

                TitleGrid.Visibility = System.Windows.Visibility.Visible ;

                Grid.SetRow(ContentGrid, 1);

                Grid.SetRowSpan(ContentGrid, 1);

            }

        }

Kodumuzda ilk olarak sayfanın OrientationChanging event'ına bir listener ataçlıyoruz. Sayfamızın zaten başında SupportedOrientations kısmında hem yatay hem de dikey desteği olduğu için telefon sağa veya sola çevrildiği anda bu event çalışacaktır. Event'ımız çalıştıktan sonra yapmamız gereken ise telefonun hangi yöne nasıl döndüğünü angılayıp sonra da ekranda gerekli değişiklikleri yapmak. Bunun için söz konusu eventa gelen OrientationChangedEventArgs parametresi üzerinden Orientation özelliğini kullanabiliriz. Eğer telefon sola veya sağa döndürülmüş ve yan tutuluyorsa basit bir şekilde ekranın üstündeki yazıyı kaldırıp resmimizin bulunduğu kısmı ana sayfada ekrana yayıyoruz. Aksi durumda, yani telefon tekrar normal şeklinde tutulduğunda ise eski ayarları tekrar yüklüyoruz. Böylece çok basit bir şekilde telefonun durumunu algılayıp uygulamamızın tepki vermesini sağladık.

Farklı tutuşlara göre tepki veren uygulamamız.
Farklı tutuşlara göre tepki veren uygulamamız.

Sanırım son bir sorun kaldı. Dikkatinizi çektiyse örnek uygulamamızda bir de menü var (ApplicatioBar) ve söz konusu menü içerisindeki düğmeler bile telefonun durumuna göre sağa sola dönüyorlar fakat ekrandan yer kaybetmemiz neden oluyorlar. Aslında biz ekranda uygulamamızın ana yüzeyi dışında hiçbirşey gözüksün istemiyoruz. İşte bu gibi bir durumda uygulamayı tam ekran moduna alabilirsiniz.

[C#]

        void MainPage_OrientationChanging(object sender, OrientationChangedEventArgs e)

        {

            if (e.Orientation == PageOrientation.LandscapeLeft ||e.Orientation == PageOrientation.LandscapeRight )

            {

                TitleGrid.Visibility = System.Windows.Visibility.Collapsed;

                Grid.SetRow(ContentGrid, 0);

                Grid.SetRowSpan(ContentGrid, 2);

                this.FullScreen = true;

            }

            else

            {

                TitleGrid.Visibility = System.Windows.Visibility.Visible ;

                Grid.SetRow(ContentGrid, 1);

                Grid.SetRowSpan(ContentGrid, 1);

                this.FullScreen = false;

            }

        }

Yukarıda gördüğünüz şekilde basit bir değişiklik uygulamanın farklı durumda tamamen tam ekran çalışmasını sağlayabilir. Böylece ekranda uygulamamızın ana ekranı dışında hiçbirşey gözükmeyecektir.

FullScreen modunda uygulamamızın görünüşü.
FullScreen modunda uygulamamızın görünüşü.

Monday, May 10, 2010 12:19:18 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 

Bugün Ankara'da BÖTE Kurultayı'ndaydım. Kullanıcı deneyimine bir göz atıp sonra da özellikle Silverlight ve WPF tarafında yazılımcı ve tasarımcıların beraber çalışmalarını sağlayan altyapılara göz attık. Benim için süper eğlenceli bir oturumdu! Oturuma katılan herkese binlerce teşekkürler ;) Etkinlikle ilgili yardımları için sevgili Davut Güneş ve Harun Uyan kardeşlerime de çok teşekkürler.

BÖTE Kurultayı, Ankara
BÖTE Kurultayı, Ankara

Gün boyunca da çok keyifli bir gün geçirdim. BÖTE Kurultay organizasonu çok başarılıydı. Sevgili hocamız Yaşar Özden ile beraber de bol bol sohbet etme şansım oldu. Vizyonerliği ve öngörüsü ile hocamız yine beni şaşırtmadı desem yalan olur. Neyse detaylar şimdilik bende kalsın :) Eh hala "Ankaraya gelmiyorsunuz hocam" diyen olursa camdan atlayacağım artık :D Unutmadan, uzun süredir görüşemediğim Murat Duman'a tüm gün boyunca beni yalnız bırakmadığı için teşekkür etmeliyim ;)

Tekrar görüşmek üzere!

Sunday, May 09, 2010 11:04:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   Silverlight 4  | 
 Saturday, May 08, 2010

Dün İzmir'de Visual Studio 2010 ve Office 2010 lansmanlarını Dokuz Eylül Üniversitesi'nde gerçekleştirdik. Ben Visual Studio 2010 ve .NET 4 tarafındaki yeniliklerden bahsettim. İzmir her zamanki gibi bir İstanbullu'nun ziyaretinde tatil havası niteliğine bürünüyor. Benim bu defa bir de müşteri ziyaretim olunca pek nefes alacak zamanım olmadı :)

Dokuz Eylül Üniversitesi, Visual Studio 2010 Lansmanı
Dokuz Eylül Üniversitesi, Visual Studio 2010 Lansmanı

Etkinlikte katkılarından dolayı Dokuz Eylül Üniversitesi MSP'lerine çok teşekkürler ;)

Saturday, May 08, 2010 6:11:58 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Visual Studio 2010  | 
 Friday, May 07, 2010

Dün akşam daha önce duyurduğumuz üzere INETA Fazla Mesai etkinliklerimizin ilkini gerçekleştirdik. Benim için çok farklı bir deneyim oldu diyebilirim. Hafta içi akşam saatlerinde katılımın bu kadar yüksek olmasını beklemiyordum. Diğer yandan katılan kesim yani özünde sizler :) konusunda da ufak bir hata yapmışız. İtiraf etmem gerek ki hafta içi akşamları sanırım biraz daha derin konulara girmek uygun olacak bundan sonraki Fazla Mesai'ler için :) Bu tabiri caiz ise çok güzel bir deneme oldu ve gerekli bilgileri topladık ;) Artık bu noktadan sonra bir sonraki Fazla Mesai'yi kaçırmayın diyebilirim :)

INETA Fazla Mesai, Mayıs 2010
INETA Fazla Mesai, Mayıs 2010

Biliyorsunuz bu etkinliğimizde yurt dışından Visual Studio ürün grubundan Suhail Dutta misafirimizdi. Oturum esnasından sizlerden gelen sorulardan yolu çıkarak çok faydalı bir iş çıkardığımızı düşünüyorum. Sanırım etkinliğin ilk oturumunun mecburen İngilizce olması da pek sorun olmadı. Sonuçta herşey demo üzerinden gittiği için ortak dilimiz malum .NET ve Visual Studio'ydu.

Ben tekrar katılan herkese, hafta içi bir akşamını bizlere ayıran herkese çok teşekkür ediyorum. Fazla Mesai etkinliğinin devam etmesini ve şekillenmesini sağlayanlar sizler oldunuz. Bunu kısa vadede sizler de görüyor olacaksınız ;)

Görüşmek üzere!

Not: Etkinlikte tüm fotoğraflara buradan ulaşabilirsiniz.

Friday, May 07, 2010 1:42:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   .NET Framework 4.0 | Visual Studio 2010  | 
 Thursday, May 06, 2010

Windows Phone 7 ile beraber gelen uygulama için navigasyon sistemlerinin bir parçası da işletim sisteminin sunduğu menü altyapısı. Bu konuda radikal bir değişikliğe giden Microsoft artık işletim sistemin ekranının altında veya üstünde (fiziksel düğmelere en yakın kısımda) bir bar göstererek söz konusu bar üzerinden komutları sunuyor. Eskiden olduğu gibi uygulamaların alt kısımda iki düğme bulunarak bu düğmelere basıldığında da açılan uzun kısmi menülere artık yer yok.

WP7'de navigasyon menüleri...
WP7'de navigasyon menüleri...

Yukarıda gördüğünüz sistemde üst kısımda gördüğünüz dört düğme sürekli olarak gözüken düğmeler oluyor ve ApplicationBarIconButton sınıfı ile yaratılıyor. Bu düğmeler bir ApplicationBar'ın parçaları arasında. Ayrıca isterseni ApplicationBar'lara ek olarak ApplicationBarMenuItem da ekleyebiliyorsunuz. MenuItem'lar normalde gözükmüyor fakat BarIconButton'ların listesinin yanında yer alan üç noktaya tıkladığınızda MenuItem'lar da sahneye geliyor ve kullanılabiliyor. Duruma göre uygulamanızın istediğiniz ekranına istediğiniz ApplicationBar'ı yaratabilir ve duruma göre IconButton ve MenuItem'ları beraber veya ayrı ayrı kullanabilirsiniz.

ApplicationBar'lar ekran başına yani PhoneApplicationPage başına yaratılabilse de genelde merkezi bir yerde tutup birden çok ekranda kullanmak daha mantıklı olabilir böylece bar arkasındaki navigasyon vs kodları da Navigation API'yi kullanıyorsa rahatlıkla uygulama içerisinde tek bir merkezi bar ile gezilebilmesini sağlayabilirsiniz. Örnek projemizde de yaratacağımız barı App.XAML içerisine koyarak merkezi hale getireceğiz, böylece barımızı tüm Page'lerde kullanma şansımız olacak.

[XAML]

<Application

   x:Class="WindowsPhoneApplication5.App"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:system="clr-namespace:System;assembly=mscorlib"

   xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"

   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone.Shell"

   xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation">

 

    <Application.RootVisual>

        <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml"/>

    </Application.RootVisual>

 

    <Application.Resources>

        <shell:ApplicationBar x:Key="MainAppBar" Visible="True">

            <shell:ApplicationBar.MenuItems>

                <shell:ApplicationBarMenuItem Text="Gel de tıklama..." Click="MenuTiklandi" />

            </shell:ApplicationBar.MenuItems>

 

            <shell:ApplicationBar.Buttons>

                <shell:ApplicationBarIconButton IconUri="1.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="2.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="3.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="4.png" Click="IconDugmeTiklandi" />

            </shell:ApplicationBar.Buttons>

        </shell:ApplicationBar>

Yukarıdaki gördüğünüz ApplicatioBar implementasyonu yapılmış bir App.XAML dosyası. ApplicationBar ve diğer kullanacağımız sınıflar Microsoft.Phone.Shell altında tanımlı olduğu için söz konusu assembly'i projemize referans olarak eklememiz sonrasında da XAML dosyası içerisinde özel bir namespace tanımlayarak import etmiş olmamız gerek. Kodun en üst kısmında kalın olarak göreceğiniz kısımda tam da bu işlemi yapıyoruz. Sonrasında sıra geliyor artık menümüz içerisinde düğmelere ve komutlara karar vermeye. Şimdilik deneme amaçlı olarak üst parafraglarda görselini gördüğümüz menüyü tanımlamak için dört adet IconButton ve bir tane de MenuItem yaratabiliriz. MenuItem'lar Text alırken IconButton'lara ise birer PNG dosya verebilirsiniz. Unutmayın PNG'lerinizi projenize ekledikten sonra Build Action olarak Content seçmeniz gerekecek. Son olarak Click eventlarını de bağlayarak kod tarafına geçebiliriz.

[C#]

        private void IconDugmeTiklandi(object sender, EventArgs e)

        {

            ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(new Uri("/OrnekSayfa.xaml", UriKind.Relative));

        }

 

        private void MenuTiklandi(object sender, EventArgs e)

        {

            ((PhoneApplicationFrame)Application.Current.RootVisual).Navigate(new Uri("/OrnekSayfa2.xaml", UriKind.Relative));

        }

Örneğimizin basitliğini korumak adına projemizde iki adet OrnekSayfa.xaml ve OrnekSayfa2.xaml adında Page olduğunu varsayalım ve IconButton'lardan herhangi birine basıldığında sayfalardan birine MenuItem'a basıldığında da diğerine yönlendirelim. Gördüğünüz üzere kod aslında olabildiğince basit. Navigation API'ye App.xaml içerisinden ulaşabilmek için uygulamanın RootVisual'ını buluyoruz ki o da zaten bizim PhoneApplicationFrame. Böylece AppFrame üzerinden de rahatlıkla Navigate metodunu çağırabiliyoruz.

Sıra geldi bu menüyü istediğimiz Page'lerle ilişkili hale getirmeye. Böylece söz konusu Page'ler uygulamada gösterilirken bu menü de ekrana gelecek.

[XAML]

<phoneNavigation:PhoneApplicationPage

   x:Class="WindowsPhoneApplication5.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"

   FontFamily="{StaticResource PhoneFontFamilyNormal}"

   FontSize="{StaticResource PhoneFontSizeNormal}"

   Foreground="{StaticResource PhoneForegroundBrush}"

   ApplicationBar="{StaticResource MainAppBar}">

 

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">

Yukarıda gördüğünüz XAML kodu herhangi bir ApplicationPage'in kodu olabilir. Önemli olan App.xaml içerisinde aslında Resource olarak tanımladığımız menümüzü alıp istediğimiz sayfaya ApplicationBar olarak atamak. Böylece artık bu sayfada bizim menü gözükmeye başlayacak.

[XAML]

<phoneNavigation:PhoneApplicationPage

   x:Class="WindowsPhoneApplication5.MainPage"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone.Shell"

   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="800"

   FontFamily="{StaticResource PhoneFontFamilyNormal}"

   FontSize="{StaticResource PhoneFontSizeNormal}"

   Foreground="{StaticResource PhoneForegroundBrush}">

    <phoneNavigation:PhoneApplicationPage.ApplicationBar>

        <shell:ApplicationBar Visible="True">

            <shell:ApplicationBar.MenuItems>

                <shell:ApplicationBarMenuItem Text="Gel de tıklama..." Click="MenuTiklandi" />

            </shell:ApplicationBar.MenuItems>

            <shell:ApplicationBar.Buttons>

                <shell:ApplicationBarIconButton IconUri="1.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="2.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="3.png" Click="IconDugmeTiklandi" />

                <shell:ApplicationBarIconButton IconUri="4.png" Click="IconDugmeTiklandi" />

            </shell:ApplicationBar.Buttons>

        </shell:ApplicationBar>

    </phoneNavigation:PhoneApplicationPage.ApplicationBar>

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneBackgroundBrush}">

Ayrıca isterseniz ApplicationBar'lar Page başına da tanımlayabilirsiniz. Yani App.xaml gibi global bir yere koymadan Bar'ları her sayfanın içine gömme şansına da sahipsiniz. Yukarıdaki XAML kodu bunun için güzel bir örnek olabilir.

Hepinize kolay gelsin.

Thursday, May 06, 2010 11:37:11 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 
 Wednesday, May 05, 2010

Windows Phone 7 içerisinden kullanıcılara doğrudan bir dosya sistemi gösterimi yapılmıyor aynı şekilde yazılım geliştiriciler de herhangi bir dosya sistemine erişim yapamıyor. Yani bizim Windows Mobile 6.x'ten alışık olduğum gibi uygulamalar dosyalarını dosya sisteminde bir yerlere kaydetmiyorlar. Kullanılacak model her uygulamanın kendi IsolatedStorage alanını kullanması. Varsayılan ayarlarla her uygulamaya 2GB kota veriliyor. Her uygulama kendi dosyalarını buraya saklayarak uygulama açıldığında da aynı alana erişerek kullanıcıya gerekli dosyaların bir listesini gösterebilir. Böylece son kullanıcı bakış açısı ile çok daha derli toplu bir sistem yaratılmış oluyor. Diğer yandan uygulamaların işletim sisteminin bulunduğu olası bir dosya sistemine erişmemesi de güvenlik açısından çoğu sorunun önünü kesiyor. Tüm bu sistem içerisinde uygulamanızın ayarları da aynı şekilde IsolatedStorage içerisinde tutulabiliyor. Bu örneğimizde WP7 içerisinde ufak bir Silverlight uygulaması yaparak kendi tanımladığımız custom bir entity'yi IsolatedStorage içerisinde uygulama ayarı olarak saklayacağız.

[XAML]

<Grid x:Name="ContentGrid" Grid.Row="1">

    <TextBox Height="74" HorizontalAlignment="Left" Margin="120,51,0,0" Name="textBox1" Text="TextBox" VerticalAlignment="Top" Width="322" />

    <TextBox Height="74" HorizontalAlignment="Left" Margin="120,131,0,0" Name="textBox2" Text="TextBox" VerticalAlignment="Top" Width="322" />

    <Button Content="Button" Height="63" HorizontalAlignment="Left" Margin="167,227,0,0" Name="button1" VerticalAlignment="Top" Width="242" Click="button1_Click" />

</Grid>

İlk olarak uygulama ekranına iki adet TextBox ve bir de Button yerleştiriyoruz. Bu TextBox'lar içerisindeki verileri bir Entity'ye aktardıktan sonra söz konusu Entity'yi de IsolatedStorage içerisinde ApplicationSetting olarak saklayacağız. Kaydetme işlemini doğrudan Button'un Click durumunda yapabiliriz.

[C#]

public class Urun

{

    public string Adi { get; set; }

    public int Stok { get; set; }

}

Yukarıdaki gördüğünüz sınıf örneğimiz için kullanacağımız basit bir Entity. TextBox'lar içerisindeki verileri ürünün adı ve stok bilgisi şeklinde ilişkilendireceğiz. IsoStore içerisinde tüm ApplicationSetting'ler birer String olarak saklanabildiği için bizim de eldeki Entity'yi bir şekilde string'e serialize etmemiz sonrasında da tabi aynı bilgisi IsoStore'dan okurken DeSerialize etmemiz gerekecek. Bunun için en uygunu hızlıca JSON formatını kullanabileceğimiz DataContractJsonSerializer sınıfından faydalanmak. System.ServiceModel.Web'i projemize referans olarak eklediğimiz gibi artık yolda devam etmeye hazırız.

System.ServiceModel.Web'i referans olarak alıyoruz.
System.ServiceModel.Web'i referans olarak alıyoruz.

[C#]

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            Urun BirUrun = new Urun();

            BirUrun.Adi = textBox1.Text;

            BirUrun.Stok = int.Parse(textBox2.Text);

 

            string json = "";

 

            using (MemoryStream ms = new MemoryStream())

            {

                DataContractJsonSerializer serializer = new DataContractJsonSerializer(BirUrun.GetType());

                serializer.WriteObject(ms, BirUrun);

                ms.Position = 0;

 

                using (StreamReader reader = new StreamReader(ms))

                {

                    json =  reader.ReadToEnd();

                }

            }

            IsolatedStorageSettings.ApplicationSettings["BizimUrun"] = json;

        }

Yukarıdaki kodumuz kaydetme düğmemizin arkasındaki kod. Kaydet düğmesine basıldığı gibi Entity'mizden bir adet yaratıp gerekli bilgileri de TextBox'lardan Property'lere atadıktan sonra bir DataContractJsonSerializer yaratarak entity'yi eldeki MemoryStream'e serialize ediyoruz. Sonunda da MemoryStream'i okuyarak String bilgiyi alıp hızlıca ApplicationSettings içerisinde Key/Value Pair tadında saklıyoruz. Artık uygulamanızı kapatıp açsanız bile sürekli uygulamanıza ait IsoStore içerisinde bu Entity bulunacaktır. Son olarak sıra geldi kaydettiğimiz bu veriyi, uygulama ayarını bir şekilde IsoStore'dan okuyarak uygulama ilk açıldığında TextBox'lara eski değerleri atamaya.

[C#]

        void MainPage_Loaded(object sender, RoutedEventArgs e)

        {

            if (IsolatedStorageSettings.ApplicationSettings.Contains("BizimUrun"))

            {

                Urun BirUrun;

                string json = IsolatedStorageSettings.ApplicationSettings["BizimUrun"].ToString();

                using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))

                {

                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Urun));

                    BirUrun = (Urun)serializer.ReadObject(ms);

                }

                textBox1.Text = BirUrun.Adi;

                textBox2.Text = BirUrun.Stok.ToString();

            }

        }

Uygulamamız ilk açıldığında IsoStore içerisinde elimizdeki Key olan "BizimUrun"'e denk gelen bir Value var mı kontrolünü yaptıktan sonra eğer daha önce veri kaydedilmiş ise hemen okuma işlemine geçiyoruz. Yeni bir Entity yarattıktan sonra eldeki String JSON değerini AppSettings'den alıp ByteArray'den MemoryStream yaratıyoruz. Geriye kalan artık söz konusu MemoryStream içerisindeki verinin DataContractJsonSerializer tarafından bir Urun nesnesine DeSerialize edilmesi. İşlem tamamlandıktan sonra da Entity içerisindeki değerleri rahatlıkla uygulama arayüzündeki kontrollere atayabiliriz.

Sonuç

Gördüğünüz gibi aslında herşey normal Silverlight development tarafı ile neredeyse bire bir aynı. Bu noktada önemli olan aslında bunun artık WP7'de uygulama geliştirme modeli olması. IsolatedStorage WP7'de çok önemli bir yere sahip ve her uygulamanın doğrudan Runtime tarafından yönetilen kendi disk alanına sahip olmasına olanak tanıyor. Böylece artık dosya sisteminde dosyayı bulup ilişkili programlama açma devri kapanıyor onun yerine ilişkili program açılıp onun içerisinden dosyaların listesi görünerek uygun dosya seçilik açılabiliyor. Tabi bu bahsettiğimiz IsoStore'un normal FileSystem modunda kullanımı, diğer yandan uygulama ile ilgili kullanıcının doğrudan kaydetme işlemi yapmadığı ve bizim yönettiğimiz veriler bu makalede gördüğümüz üzere ApplicationSetting olarak saklanabiliyor.

Hepinize kolay gelsin.

Wednesday, May 05, 2010 6:17:19 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows Phone 7  | 
 Tuesday, May 04, 2010

Bu hafta Perşembe günü (06.05.2010) yeni bir INETA serisine başlıyoruz! "INETA FAZLA MESAİ" olarak adlandırdığımız bu seride amacımız olabildiğince iş hayatından community aktivitelerine zaman ayıramayan yazılımcılara biraz fazla mesai yaptırmak :) İlk aktivitemizi bira geç duyurduğumuzun farkındayım. Fakat nedenini birazdan vereceğim bomba haber açıklayacaktır :) İlk aktivitemizde Microsoft'tan Visual Studio Ürün Grubu Kıdemli Program Yöneticisi (Senior Program Manager) Suhail Dutta bulunacak! Sunacağı "Uygulamalarınızı Visual Studio 2010 kullanarak tanıyın" oturumu aslında çoğumuzun genelde karşılaştığı bir sorunu hedefliyor. Hani elinize proje gelir kodlarını hiç bilmediğiniz, yapısını hiç tanımadığınız. İşte bu gibi projelere Visual Studio 2010 araçları ile yaklaşıp projeleri tanımanın ve keşfetmenin yeni yollarını anlatacak Suhail Dutta. Bir saat sürecek bu oturumun sonrasında benim de bir saatlik bir Parallel Programlama oturumum olacak ;)

INETA Fazla Mesai'de Shuail Dutta!
INETA Fazla Mesai'de Shuail Dutta!

Microsoft Istanbul ofisinde olacak bu etkinliğe katılım tamamen ücretsiz. Katılım sınırlı olacağı için tavsiyem hemen www.inetatr.org üzerinden kayıt olmanız! Suhail'in oturumu İngilizce olacak fakat demo ağırlıklı olacağı için İngilizce bilmeyenler için de sorun olmayacağından eminim. Benim oturumum ise tabi ki Türkçe olacak. Görüşmek üzere!

Tuesday, May 04, 2010 8:37:53 AM (GTB Standard Time, UTC+02:00)  #    Comments [3]   Visual Studio 2010  | 
 Monday, May 03, 2010

Bu makalemizde Windows Phone 7 içerisinde uygulama geliştirirken kullanabileceğimiz hazır gelen navigasyon sistemine göz atacağız. Fakat bunun öncesinde tavsiyem benzerliklerinden dolayı Silverlight 3.0 içerisindeki Navigation API'yi bir incelemeniz. Sonrasında WP7 tarafında devam edebiliriz.

WP7 Kullanıcı Arayüzü Yapısı
WP7 Kullanıcı Arayüzü Yapısı

Her yeni yaratılan WP7 uygulamasında root element bir PhoneApplicationFrame olarak gelir. Bu çerçeve içerisinde birden çok sayfa farklı navigasyonlarda rahatlıkla gösterilebilir. Bu yapı kendi içerisinde SystemTray ve ApplicationBar'ı da sunar. Ayrıca PhonePage olarak geçen uygulama içerisindeki her sayfa da bu Frame tarafından gösterilir. Sayfalar ile kabaca iki bölüme ayrılır. Sayfa başlığının bulunduğu Title kısmı ve sayfanın tüm iç kontrollerinin bulunacağı Content bölümü.

[XAML]

<Application

   x:Class="WindowsPhoneApplication4.App"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:system="clr-namespace:System;assembly=mscorlib"

   xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"

   xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation">

 

    <!--RootFrame points to and loads the first page of your application-->

    <Application.RootVisual>

        <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml"/>

    </Application.RootVisual>

Yukarıda gördüğünüz kod herhangi bir WP7 uygulamasının App.XAML dosyasında ilk yaratıldığında bulunan kod. Kod içerisinde uygulamanın RootVisual'ı olarak bir PhoneApplicationFrame atandığını görebiliyoruz. Söz konusu PhoneApplicationFrame Microsoft.Phone.Controls.Navigation assembly'si altında Microsoft.Phone.Controls namespace'inde bulunuyor. Bahsettiğimiz namespace zaten phoneNavigation adında bir XML namespace olarak XAML dosyasında tanımlanmış durumda. PhoneAppFrame'in ilk açılıştaki Source değeri uygulama ilk açıldığında gösterilecek sayfayı yani PhoneApplicationPage'i hedefliyor. Söz konusu tanımlama XAP dosyasının iç yapısına ait bir Uri. Tam da bu noktada eğer istersek farklı UriMapping kuralları da tanımlayabiliyoruz ve buradaki Navigation API'yi aynı normal Silverlight uygulamalarında olduğu gibi kullanabiliyoruz.

[XAML]

<Application

   x:Class="WindowsPhoneApplication4.App"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:system="clr-namespace:System;assembly=mscorlib"

   xmlns:mpc="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"

   xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"

   xmlns:nav="clr-namespace:System.Windows.Navigation;assembly=Microsoft.Phone.Controls.Navigation">

 

    <!--RootFrame points to and loads the first page of your application-->

    <Application.RootVisual>

        <phoneNavigation:PhoneApplicationFrame x:Name="RootFrame" Source="/MainPage.xaml">

            <phoneNavigation:PhoneApplicationFrame.UriMapper>

                <nav:UriMapper>

                    <nav:UriMapper.UriMappings>

                        <nav:UriMapping Uri="/urun/{ID}" MappedUri="/Sayfalar/Page1.xaml?ID={ID}"/>

                    </nav:UriMapper.UriMappings>

                </nav:UriMapper>

            </phoneNavigation:PhoneApplicationFrame.UriMapper>

        </phoneNavigation:PhoneApplicationFrame>

    </Application.RootVisual>

Yukarıdaki XAML kodu içerisinde önemli birkaç nokta var. Bunlardan ilki XAML NameSpace olarak tanımladığımız nav namespace'i. NAV NameSpace'i de yine Microsoft.Phone.Controls.Navigation assembly'si içerisinde fakat bu sefer System.Windows.Navigation altında gelen sınıfları kullanmanız gerekiyor. İstediğimiz şey bizim PhoneAppFrame için bir UriMapper tanımlamak. Böylece uygulama içerisinde vereceğimiz farklı linkler doğrudan XAP dosyası içerisinde path'lere (Uri'lere) dönüşebilecek ve uygun XAML dosyası (PhoneAppPage) sahneye gerekli parametrelerle getirilebilecek.

Örneğimizde sadece bir adet mapping var. Herhangi bir şekilde /urun/1 veya /urun/2 gibi bir adrese yönlendirme yapıldığında söz konusu sondaki ID'yi alarak XAP dosyası içerisinde Sayfalar klasöründe bulunan Page1.XAML adındaki bir dosyaya ID parametresi olarak gönderiyoruz. Yazım esnasında {Degisken} şeklinde tanımladığınız her deyim aslında birer local değişken gibi davranarak sizin gelen path'den bir değeri alarak yarattığınız hedef path'e aktarmnızı sağlıyor. Bu şekilde tanımlanan Mapping'ler kullandığınız PhoneAppFrame içerisindeki tüm navigasyonlarda otomatik olarak uygulanacaktır.

Sayfalar klasörü ve içerisindeki View'lerimiz....
Sayfalar klasörü ve içerisindeki View'lerimiz....

Tabi bu noktaya kadar biz ne Sayfalar klasörü yarattık ne de içinde Page1.xaml adında bir dosya var. O nedenle şimdi gelin XAP içerisinde bir Sayfalar klasörünü yukarıdaki ekran görüntüsündeki gibi yaratalım ve içerisine de yeni bir "Windows Phone Portrait Page" ekleyelim.

Uygulamamız yeni bir Page ekliyoruz.
Uygulamamız yeni bir Page ekliyoruz.

Eklediğimiz bu sayfa bizim daha önce App.XAML içerisinde tanımladığımız UriMapper'daki kurallar sayesinde çağrılacak. Hatırlarsanız mapping kuralı içerisinde Sayfalar/Page1.xaml?ID={ID} demiştik ve {ID} yerine de mapping esnasından uygun değer yerleştirilecekti. Peki Page1.XAML nasıl olacak da bu ID değerine ulaşacak. Her zamanki gibi Navigation API ile beraber gelen sistemi kullanacağız.

[C#]

        void Page1_Loaded(object sender, RoutedEventArgs e)

        {

            ListName.Text = this.NavigationContext.QueryString["ID"].ToString();

        }

Yukarıda gördüğünüz kod Page1.XAML içerisinde gelen ID parametresini yakalamanın yolu. Normal bir ASP.NET uygulamasını QueryString almaktan pek farklı değil. Artık sayfa içerisinde gelen parametreye göre farklı bilgiler gösterebilir, işlemler yapabilirsiniz. Şimdilik örneğimizde sadece gelen ID'yi ekrana yansıtıyoruz ki test edebilelim.

Mapping sistemimiz hazır, hedef sayfamız hazır ve kendisine gelen parametreyi dinliyor. Son adım olarak ana sayfada bu hedef sayfaya link vermek kaldı.

[XAML]

<Grid x:Name="ContentGrid" Grid.Row="1">

    <HyperlinkButton Content="HyperlinkButton"

                            Height="30" HorizontalAlignment="Left"

                            Margin="230,217,0,0" Name="hyperlinkButton1"

                            VerticalAlignment="Top" Width="200"

                            NavigateUri="/urun/1"/>

</Grid>

Kodumuzda basit bir HyperlinkButton kullanarak tek yapmamız gereken NavigateUri özelliğine istediğimiz Uri'yi vermek. Örneğimizde /Urun/1 adresini verdiğimiz bu adres UriMapper tarafından /Sayfalar/Page1.xaml?ID=1 şekline çevrilecek ve uygulama ekranında Page1.XAML'ı 1 ID değerini almış olarak göreceğiz. Eğer bu yönlendirme işlemini doğrudan bir kod ile yapmak isterseniz aşağıdaki gibi yine NavigationService üzerinden Navigate metodunu kullanarak Frame'i yönlendirebilirsiniz.

[C#]

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            this.NavigationService.Navigate(new Uri("/urun/2", UriKind.Relative));

        }

Hepinize kolay gelsin.

Monday, May 03, 2010 5:18:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 4 | Windows Phone 7  | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.