Makale Özeti

Bu makalemizde, RSS okuyan ve onları bir ADO.NET DataSet içinde yükleyen bir Windows Mobile 5.0 uygulamasını nasıl yapabileceğimizi göreceğiz. İlk olarak, asenkron olarak URL den RSS leri nasıl talep edeceğimizi göreceğiz. Daha sonra, bu RSS leri nasıl okuyup, bir DataSet içine atabileceğimize bakacağız. Bir sonraki adım da, bu DataSet içinde, RSS öğesini içeren uygun verileri bulabilmek için uygulama içinde nasıl gezinebileceğimize bakacağız. Daha sonra da, verileri sıralamak, ADO.NET kullanarak RSS içinde olup olmadığını kontrol etmek ve WebBrowser kontrolünü kullanarak; HTML i göstermek ya da belirli URL ye gidebilmek için neler yapabileceğimize bakacağız. Son olarak da, CAB projesi kullanarak bir mobil aygıta uygulamayı nasıl deploy edeceğimizi göreceğiz.

Makale

Smartphone Üzerinden RSS'leri Okuma

Mobil uygulamalarının diğer uygulamalardan hiçbir farkı yoktur. Onlar da veriyi işler, bir bağlantı üzerinden veri ile haberleşebilir ve bu verileri belirli amaçlar çerçevesinde yönetir. Artık mobil uygulamalar birçok açıdan çok daha karmaşık hale geldiği gibi, onları geliştirmek için kullandığımız araçlar da aynı şekilde karmaşıklaştı. Aslında, Microsoft .NET Compact Framework 2.0 kullanarak veri merkezli mobil uygulamalar geliştirirken; bildik Windows uygulamalarında ne yapıyorsak aynı şeyleri bu mobil uygulamalarda da yapar hale geldik. .NET Compact Framework ile yazılım geliştirciler, mobil cihazlar üzerinde veri işlemleri gerçekleştirebilmek için ADO.NET ve benzer kütüphaneleri kullanabilir hale geldiler.

Smartphone lar için birşeyler geliştirme durumunda ise bizi küçük ekran boyutlarının yönetimi gibi tasarım ile ilgili bazı zorluklar bekler. Buna ek olarak, mevcut internet bağlantısı da uygulama tasarımını etkiler.

İşte bu makalemizde de, RSS okuyan ve onları bir ADO.NET DataSet içinde yükleyen; bir Windows Mobile 5.0 uygulamasını nasıl yapabileceğimizi göreceğiz. İlk olarak, asenkron olarak URL den RSS leri nasıl talep edeceğimizi göreceğiz. Daha sonra, bu RSS leri nasıl okuyup, bir DataSet içine atabileceğimize bakacağız. Bir sonraki adım da, bu DataSet içinde, RSS öğesini içeren uygun verileri bulabilmek için uygulama içinde nasıl gezinebileceğimize bakacağız. Daha sonra da, verileri sıralamak, ADO.NET kullanarak RSS içinde olup olmadığını kontrol etmek ve WebBrowser kontrolünü kullanarak; HTML i göstermek ya da belirli URL ye gidebilmek için neler yapabileceğimize bakacağız. Son olarak da, CAB projesi kullanarak bir mobil aygıta uygulamayı nasıl deploy edeceğimizi göreceğiz.

Başlamadan Önce

Her zamanki gibi bir mobil uygulama geliştirirken bir “başlamadan önce” başlığı atma gereksinimi hissediyorum. Aslında .NET Compact Framework 2.0 Visual Studio 2005 ile bir mobil uygulama geliştirme, bir çok yönleriyle ASP.NET ya da Windows uygulaması geliştirmeye benzer. Yine de kod yazmaya başlamadan önce, bazı şeyleri yapmamız gerekiyor. Şimdi, makinanıza çoktan Visual Studio 2005 yüklediğinizi varsayarak; aşağıda vermiş olduğum listenin de makinanızda olduğundan emin olun. Yok eğer değilse, gerekli olanları, hemen Microsoft'un Web sitesinden indirebilirsiniz.

Geliştirme esnasında gerçek bir Smartphone cihazınız olmasa bile, onun yerine emülatörümüz var. Onu indirip kolaylıkla kurabilirsiniz. Yine ActiveSync in son sürümünü yüklemeniz gerekiyor. Bunu emülatöre uygulamayı deploy etme ve emülatörün Internet'e bağlanabilmesi gibi amaçlar için kullanacağız. Windows Mobile SDK 5.0 for Smartphone ise, Smartphone için uygulama geliştirme de kullanabileceğimiz ona özel bir kaç proje tipini, Visual Studio 2005 e ekler (Aynı SDK dan PocketPC içinde var. Bir de ek olarak Windows Mobile 6 SDK ları da çıktı. Onlara da bir göz atabilirsiniz). Son olarak da direk olarak hedef cihaza uygun olan emülatörü yüklemelisiniz. Buradaki uygulamamız için hedef cihazımız ise, 320x240 ekrana sahip bir Smartphone.

Biraz emülatörlerden bahsedelim. Bilindiği üzere, yeni versiyonları ile birlikte mobil teknolojiler üzerinde yazılım geliştirenler için birçok kolaylıklar getirildi. Bunlardan bir tanesi de bol miktarda desteklenen emülatör çeşitleriydi. Eskiden emülatörü sadece küçük uygulamalar için kullanıp, test işlemlerini gerçek cihazlar üzerinde yapıyorduk. Ama bazen eğer gerçek, uygun cihazı bulamazsak, bu gerçekten problem oluşturuyordu. Şimdilerde ise sağlanan birçok emülatör çeşidi ile bir cihaza bağlı kalmadan geliştirme yapabiliyoruz. Zaten önemli olan nokta da işte burada ortaya çıkıyor. Mobil üzerine platform geliştiren kişiler, öncelikle yazılım geliştiricilerin bu açığını gidermek zorundalar. Onların herhangi bir cihazı satın almalarına gerek kalmadan uygulamalarını test edebilmelerini, çalıştırabilmelerini sağlayacak emülatörler geliştirebilmeleri gerekir. Şimdilerde ise bu büyük ölçüde sağlanmış durumda. Peki neden emülatör? Bunun için birkaç nedenimiz var. Hep birlikte bakalım.
  • Windows Mobile yazılım geliştirme platformu kendi içinde çok tutarlı. Bu yüzden de emülatörler için sağlanan API ler, gerçek aygıtlar için sağlanan API ler ile de çok tutarlı bir şekilde çalışıyor.
  • Gerçek aygıtlar gerçekten çok pahalı (özellikle aygıt ve servis bir arada olursa).
  • Bulunduğunuz bölgede istediğiniz, hedeflediğiniz cihazı her zaman satın alamayabilirsiniz. Örneğin, biz Avrupalı yazılım geliştiriciler, Q ya kolay bir şekilde ulaşıp satın alamayabiliriz.
  • Farklı aygıt geliştiricilerinin sürekli çoğalmasıyla oluşan faktörler. Kendinizi devamli güncel tutmak istediğinizde her cihazı almak gerçekten pahalı olabilir. Onlara uygun yazılımlar geliştirmek de zaman kaybından öteye gidemez.
Son birkaç yıldır aygıtlar için hazırlanmış emülatörler de gerçekten de inanılmaz, büyük gelişmeler sağlandı (Windows Mobile Team, thank you :) ). Performansı son seviyelere çıkarılmış, gerçek ARM emülasyonu artık var. Özellikle Windows Mobile 6 da, GPS uygulamalarını test etme ve cep telefonu işlemleri ile etkileşimleri test etmek için birçok yeni fonsksiyonel özellik geliyor. Emülatörler sayesinde, eğer pazara yeni bir cihaz gelmişse, yeni form faktörlerini destekleyebilmek için hemen emülatör yamaları çıkarılabiliyor. Örneğin, Q ve Blackjack lanse edildiklerinde, onları desteklemek için hemen Smartphone Landscape emülatörü yayınlanabildi.

Son söz olarak da şunu ilave edelim. Eğer gerçekten bir cihazınız varsa tümüyle emülatör kullanmak yerine uygulamayı onun üzerinde test edebilirsiniz. Emülatör her ne kadar inanılmaz, önemli bir araç olsa da, herşeyden emin olmak ve gerçek ortamında test etmek için gerçek cihazlara gereksinim duyulabilir. Yok eğer yoksa en iyisi emülatör ile devam etmektir.

Kodu çalıştırmadan önce, Visual Studio'nun Tools menüsünden Device Emulator Manager ı çalıştırmanız gerekir. Burada uygun emülatörlerin bir listesi ekrana gelecektir. Bu listeden siz 320×240 (Landscape) Windows Mobile 5.0 Smartphone Emulator ü seçin. Eğer bu seçeneğini henüz yüklemediyseniz, herhangi bir Windows Mobile 5.0 Smartphone emülatorü seçebilirsiniz. Yalnız bu makaledeki kodlar, 320×240 ekrana sahip bir Smartphone düşünülerek yazılmıştır. Fakat, diğer çözünürlüklere rahatlıkla uyarlanabilir.

Emülatörü seçer seçmez, üzerine sağ tıklayın ve “Connect” i seçin. Emülatör Smartphone u boot etmeye başlayacaktır. Emülatör de Smartphone çalışır çalışmaz, yine Device Manager da cihaz üzerine sağ tıklayın ve “Cradle” ı seçin. Emülatörü cradle etme, Smartphone nun ActiveSync ile haberleşebilmesini sağlayacaktır. Bu da, Internet e erişebilmek ve RSS leri yakalayabilmemiz için cihazın ağınıza bağlanabilmesine olanak verecektir. Son olarak da, Visual Studio içinde, Device araç çubuğundaki listeden 320x240 emülatörünü seçin. Bu, Visual Studio ya hangi emülatör resminin, debug ve deploy işlemlerinde kullanılacağına söyler.

RSS Okuyucu Uygulaması

Koda dalmadan önce, uygulamamızın neler yapacağına ve nasıl görüneceğine bir bakalım. Uygulama çalıştırıldığında, uygulamamız, belirli Web sitelerinden RSS leri asenkron olarak talep edecek ve onları, her bir RSS in başlığını ve herbirinin döndürdüğü öğe sayısını içerecek olan bir ListView kontrolünü yükleyecek. Aşağıdaki resimden nasıl göründüğüne bakabilirsiniz.

RSS Listesi

RSS İçindeki Öğelerin Listesi

Öğe İçindeki Açıklamalar

RSS yayın başlığını seçtiğinizde ve ister soft key i (Smartphone un ortasındaki tuş) kullanarak ister de Menü den Select i seçerek; başlığa tıkladığınızda, seçilen RSS listesindeki tüm öğeler bir başka formda, en yeni olan en üstte olacak şekilde listelenecektir. Eğer RSS öğelerin yayın tarihini (RSS şema içinde opsiyonel bir element) içeriyorsa, o da listenin ikinci sütununda görülecektir. Eğer herhangi bir yayın tarihi yoksa, bu sütun atılacak ve sadece öğe başlığı ekrana gelecektir.

Öğeyi de aynı şekilde seçer seçmez, açıklaması başka bir ekranda karşınıza gelecektir. Öğe açıklaması elementinde bulunan tüm içerik, bir WebBrowser kontrolü içinde gösterilecektir.

RSS içindeki açıklama elementi direkt olarak okunduğu için, öğe açıklaması link ve resim içerebilir. Eğer URL içeriyorsa, kullanıcı URL ye tıklayarak; bu adrese gidebilir. Eğer kullanıcı, öğenin açıklaması gösterilirken; soft key i kullanarak Select menüsüne tıklarsa, uygulama bir başka ekrana geçer ve seçili öğenin belirttiği URL ye içeriğini WebBrowser kontrolüne yükleyerek gider. Kullanıcı ne zaman bir önceki sayfaya dönmek isterse geri soft key ini kullanarak bir önceki ekrana dönebilir. “Feed Item List” ekranından da, kullanıcı, menüden sol soft key ini kullanarak “Done” ı seçebilir ve uygulamadan çıkabilir.

Bu uygulama, bu tip bir uygulama içinde kullanabileceğiniz ya da eklemeniz gereken temel özellikleri gösterir. Fakat isterseniz uygulamayı daha karışık ve zengin hale getirebilirsiniz. Progress bar lar, ikonlar ve RSS listelerini kontrol edebilmek için ne varsa uygulamaya ekleyebilirsiniz. Kod üzerinde istediğiniz herşeyi yapmak da özgürsünüz. Hayal gücünüze kullanarak; dilediğiniz tüm geliştirme ve iyileştirmeleri yapabilirsiniz.

Asenkron RSS İstekleri

Şu ana kadar uygulamamızın nasıl çalışacağına biraz olsun baktık. Şimdi ise biraz kod yazalım. Uygulama yüklendiğinde, ilk olarak 4 RSS listesi (aşağıdaki kodda bunları görebilirsiniz) için belirli URL ler boyunca dönerek ve BeginScanFeeds methodunu her biri için ayrı ayrı çağırarak istemde bulunulur.

BeginScanFeeds metodu, belirli bir URL için HttpWebRequest sınıfının bir örneğini yaratır. Bu istek, daha sonra HttpWebRequest' in BeginGetResponse metodunu kullanarak verilen URL için asenkron olarak gerçekleştirilir. Bu methot asenkton callback lerini (burada ise EndScanFeeds metodu) ve isteğini kabul eder.

Her bir istek gönderildiğinde ve karşılığı döndüğünde, EndScanFeeds metodu çalıştırılır. EndScanFeeds metodu, bilgiyi çekmede kullanımak üzere IAsyncResult tipinin tek bir argümanına sahiptir. Aşağıdaki kodda, StreamReader nesnesi kullanarak HttpWebResponse nesnesinden dönen isteği feedData isimli string in içine koyan bu metodun kod parçacığını bulabilirsiniz. feedData string i RSS in XML verisini içerir ve bu string RSS verisini ListView kontrolünün içine yükleyecek olan LoadFeedList metoduna geçirir. RSS verisi asenkron olarak okunduğu ve LoadFeedList metodu ListView kontrolüne eriştiği için, metodun Control.Invoke metodu kullanılarak çağrılması gerekir.

RSS'leri Okuma

DataSet'e Yükleme

RSS feed i alınır alınmaz, içeriği ayrıştırılmalıdır. XML string ini okumak için birçok yol olsa da, burada, biz onu aşağıdaki kodu kullanarak bir DataSet in içine yükleyeceğiz.

Sütunların olup olmadığını kontrol edebilme ve RSS feed hiyarşisi içinde gezinebilme gibi özellikleri bize sağladığı için bu yaklaşımı seçiyoruz.

Feed in içeriği, daha sonra XmlTextReader ı yaratmada kullanılacak olan StringReader nesnesine yükleniyor. XmlTextReader daha sonra, DataSet in içerisine feed in içeriğini yükleyen DataSet in ReadXML metodu tarafından okunuyor. RSS şeması, kendi hiyerarşisi içinde temel olarak 3 ana eleman içerir: rss, channel ve item (bazı şemalar, images elementi gibi daha fazla element içebilir).

Rss elementi, tek ya da daha fazla channel elementi içeren RSS feed inin köküdür. Channel elementleri feed i temsil eder ve feed i tanımlayan birçok child element serisi (title, link, description ve item gibi) içerebilirler. Item elementi, channel elementinin gerekli bir elemanıdır (bu arada, bu main item element i değildir.). Item elementleri feed içerisindeki herbir öğeyi temsil ederler. Örneğin, MSDN bloğu içerisinde, channel MSDN Blog u iken, items, mesajları temsil eder.

RSS feed i DataSet in içerisine yüklendiğinde, ana elementler - rss, channel ve item – tablolar olarak yüklenirler. Hiyerarşinin her bir seviyesi DataTable olur ve DataTable ın özellikleri kullanılarak okunabilir ve üzerinde gezinilebilir. Herbir ana elementi tanımlayan basit child elemenleri de kendisine karşılık gelen DataTable içinde sütunlar olarak yüklenirler. Örneğin, channel DataTable ı öğe (item), açıklama (description) ve link elementleri için bir DataColumn içerir (bu üç element, zorunlu elementlerdir).

Son olarak, DataRelation, channel DataTable ve item DataTable arasında yaratılır. Bu ilişki, kullanıcı belirli bir feed i seçtiğinde; uygulamanın belirli channel öğelerini göstermesinde kullanılacaktır.

Feed Listelerini Yükleme

Feed DataSet e yüklenir yüklenmez, kanal tablosuna konumlanıyoruz ve kanal başlığı ve her bir kanalın içerdiği öğe sayısını yakalıyoruz. Bu bilgiyi bir dizi içerisinde saklıyor ve feed ler alındığında, onları bir list view içerisine yüklüyoruz. Aşağıdaki kodda bunun nasıl gerçekleştiğini görebilirsiniz.

Feed Listelerini Yükleme

Kanal başlığına, standart ADO.NET syntax i kullanılarak; DataRow sütunundan değerleri okuyarak erişiliyor. Her bir kanaldaki toplam öğe sayısını almak için, o anki kanal satırının öğeleri için DataRow nesnesinin dizisini döndüren DataRow un GetChildRows metodunu kullanıyoruz. Bu arada dikkat etmenizde yarar var; ListViewItem etiketi içinde kanalın DataRow a referansını saklıyoruz. Bu, kullanıcı belirli bir feed i seçtiğinde, feed bilgisini kolaylıkla yakalayabilmemizi sağlayacak.

Sıralama

Kullanıcı feed i seçtiğinde, DataRow, FeedItemList formuna geçiriliyor. O da daha sonra ListView kontrolü içerisine öğelerin bir listesini yüklüyor. Burada eğer sağlanıyorsa yayın tarihi ve öğenin başlığını yüklüyoruz. pubDate elementi RSS 2.0 şeması içinde olması gereken bir element olmadığı için, öncelikle DataTable içerisinde bu sütunun olup olmadığını kontrol ediyoruz. Feed öğelerini temsil eden DataRow nesnesinin bir dizisine sahip olduğumuz için, bunu DataRow un DataTable nesnesini bulmak için kullanabiliyoruz ve daha sonra da pubDate sütununun olup olmadığını kontrol etmek için DataTable.Columns.Contains metodunu kullanıyoruz. Çok şey yapıyormuşuz gibi gözükse de, aşağıda gördüğünüz gibi aslında kodu oldukça basit.

pubDate in olup olmadığını belirler belirlemez, daha sonra list view içerisinde öğeleri nasıl göstereceğimizi ve sıralayacağımızı belirliyoruz. Eğer pubDate varsa, öğeleri tarihe göre azalan sırada listeliyoruz. Eğer yoksa, öğeleri başlığa göre listeliyor ve list view içerisinde yayın tarihi sütununu gizliyoruz. Tüm bu yapılanları aşağıdaki kodda görebilirsiniz.

Uygulamanın hem öğenin başlığını hem de yayın tarihini gösterebilmesi için sütun genişlikleri ayarlanıyor. Daha sonra da DataRow nesnelerinin dizisinin sıralanabilmesi için Array.Sort metodu kullanılıyor. Tarihleri sıralamadan öncei onları uygun DateTime çeviriyoruz. Çevirme işlemi biter bitmez, DataRow dizisini sıralamak için özel karşılaştırma temsilcisini kullanıyoruz.

Bu özel karşılaştırma temsilcisi oldukça güzel. Klasik sıralama işlemleri için yazılan koda kısa bir yol. Sıralama sürecini kendi yazdığımız kod ile de güzelleştirebilirdik ama yazdığımız kodu minimuma indirmek istediğimiz için, bu özel karşılaştırma temsilcisi iyi bir seçenekti. Tarihlerin sıralanması, dizi içerisinde her bir element için gerçekleştiriliyor. Bu örnekte, iki DataRow nesnesi alan bir temsilci yaratıyor ve onları kendi pubDate sütunlarındaki değerleri değerlendirerek karşılaştırıyoruz.

Eğer pubDate sütunu yoksa da (koddaki else bölümü çalışıyor), list view içerisinde ikinci sütunu gizliyor ve ilk sütunu tüm ekranı kaplayacak şekilde genişletiyoruz. Daha sonra da, DataRow dizisini öğe başlıklarına göre artan sırada listeliyoruz. Burada da aynı tekniği kullanıyoruz. Bu sefer sadece string değerlerini karşılaştırıyoruz.

Bu metot, karşılaştırma fonksiyonlarını tekrar tekrar kullanmanıza gerek olmadığı zaman mevcut kodun azaltılmasına yardımcı olan gerçekten güze bir yol sunuyor bize.

DataRow dizisi sıralanır sıralanmaz, aşağıdaki kodda da görebileceğiniz gibi, her bir öğeyi bir döngü boyunca işliyor ve öğelerin başlığını ve yayın tarihlerini (eğer varsa) yakalıyor. Burada elde edeceğimiz sonuç eğer pubDate ler varsa, aynı RSS İçindeki Öğelerin Listesi başlığı ile verdiğimiz resimde olduğu gibi listelenecektir.

WebBrowser Kontrolü İle Gösterim

Kullanıcı öğeyi seçtiği anda, seçili ListViewItem sorgulanır ve seçili öğenin DataRow u, Tag özelliğinden alınır. Seçili öğeyi içeren DataRow, seçili öğenin açıklamasını gösterecek olan ItemSummary formu için bir constructor a aktarılır. Burada, öğenin açıklamasını göstermek için klasik label etiketi kullanmadığımıza dikkat edin. Bunun sebebi, RSS feed leri içerisindeki açıklama metinleri genellikle gömülü HTML kodları içerir. Bu yüzden, açıklamayı göstermek için WebBrowser kontrolü kullandık.

Öğe İçindeki Açıklamalar başlıklı resimde gösterildiği gibi, öğe açıklamasının özeti bir WebBrowser kontrolü içerisinde gösterilir. Link, resim ve diğer HTML elementlerini içeren bu özet açıklamayı görebilirsiniz. HTML i çalıştırabilmek için, öğenin açıklamasına WebBrowser kontrolünün DocumentText özelliğini ve başlığına da formun Text özelliğini ayarlıyoruz.

Bu uygulamada, WebBrowser kontrolü iki amaç için kullanılır. HTML içeren ya da içermeyen öğe açıklamalarını ItemSummary formunda göstermek için kullanılır. Bir de öğenin DataRow u içerisinde belirli linklere gidebilmesi için Item formu tarafından kullanılır. Bu, WebBrowser kontrolününü kullanmanın en bilinen yoludur.

Burada, Item formunun başlığını öğenin başlığına atadık ve böylelikle WebBrowser kontrolü içerisinde Navigate metodunu kullanarak; öğenin URL sine gidebiliyoruz. Bağlantı linki daha sonra konumlandırılıyor ve sayfa, WebBrowser kontrolü içerisine yükleniyor.

Smartphone'a Deploy İşlemi

Uygulamayı build eder etmez, onu gerçek bir Smartphone cihazına deploy edebiliriz. Bu noktada, emülatörü ve Device Emulator Manager ı kapatın. Böylelikle, deployment işlemini tamamı ile Smartphone üzerinde gerçekleştirebiliriz.

Uygulamayı deploy etme hakkında birkaç not. Öncelikle, Smartphone Device CAB projesi yaratmalısınız ve onu mevcut solution dosyamıza eklemelisiniz. .NET Compact Framework 2.0 kullanarak build ettiğimiz uygulamamızı çalıştırabilmek için, Framework de mobil cihazımız da yüklü olmalı. Bu iki adımı gerçekleştirir gerçekleştirmez, CAB dosyasını mobil aygıtınıza kopyalayabilir ve uygulamayı direk olarak yükleyebilirsiniz.

Özet

Bu makalede, ilk olarak uygulamamızı nasıl oluşturacağımızı ve gerekli araçları gördük. Ek olarak biraz emülatörlerden bahsettik ve uygulamamızın bittiğinde nasıl çalışacağı üzerine fikir sahibi olduk. Daha sonra da, biraz kod yazarak, RSS okuyan ve onları bir ADO.NET DataSet içinde yükleyen; bir Windows Mobile 5.0 uygulamasını nasıl yapabileceğimizi gördük. İlk olarak, asenkron olarak URL den RSS leri nasıl talep ettik, bu RSS leri okuyup, bir DataSet içine nasıl atabileceğimize ve DataSet içinde, RSS öğesini içeren uygun verileri bulabilmek için uygulama içinde nasıl gezinebileceğimize baktık. Sonra, verileri sıralamak, ADO.NET kullanarak RSS içinde olup olmadığını kontrol etmek ve WebBrowser kontrolünü kullanarak; HTML i göstermek ya da belirli URL ye gidebilmek için neler yapabileceğimizi gördük. Son olarak da, CAB projesi kullanarak bir mobil aygıta uygulamayı nasıl deploy edeceğimizi öğrendik.

Son söz olarak bir şey daha. .NET Compact Framework 2.0 ile veri merkezli mobil uygulamalar geliştirirken, Windows uygulaması geliştirirken kullandığınız birçok benzer özelliği mobil uygulamalarda da kullanabilirsiniz.

Kaynak: MSDN

Bir sonraki makalelerde görüşmek üzere. İyi çalışmalar...


Tayfun AKCAY

tayfun@tayfunakcay.com