Bu hafta sonu INETA Professional Hit etkinliğimizi
gerçekleştirdik. Kayıt alımındaki sorunlara karşın etkinlik boyunca gelen olumlu
tepkiler epeyce moralimi düzeltti. Level 300 hedefi ile yola çıksak da maalesef
beni dinlemeyip :) oturumlardaki konularla ilgili hiç çalışmamış arkadaşlar da
geldi! Umarım bir sonraki Level 300 etkinliğimizin seviyesi ile ilgili biraz da
olsa fikir oluşmuştur kafalarda. Özellikle benim Silverlight oturumunda salonun
yarısının hiç Silverlight ile ilgilenmemiş olması Level 300 seviyelerine
çıkmamızı engelledi diyebilirim.
 INETA Professional Hit İlk Gün
Neyse :) Bu her açıdan bir "ilk"ti ve hepimiz Level 300 seminerlerle ilgili
bir şeyler öğrendik. Bir dahakinin daha verimli olması için bazı notlar da aldık
kenara. Şimdi sıra geldi artık fotoğrafları :) ve örnek kodlar ile sunumları
sizlerle paylaşmaya.
http://cid-8eca4439fd9a640f.skydrive.live.com/browse.aspx/INETA%20Professional%20Hit%20012009
Yukarıdaki adresten tüm fotoğrafları orijinal çözünürlükleri ile
indirebilirsiniz. Ayrıca yukarıdaki adreste bir de Ozel.rar dosyası göreceksiniz
:) O dosya içerisinden de kişisel çekilmiş fotoğraflar var.
 INETA Professional Hit 2. Gün
Son olarak aşağıdaki download linklerinden de her oturumla ilgili örnekleri
ve sunumları indirebilirsiniz.
28012009_ADONET.rar (1,13 MB)
28012009_AJAX.rar (75 KB)
28012009_CSHARP.rar (551,66 KB)
28012009_LifeCycle.rar (126,8 KB)
28012009_Silverlight.rar (672,98 KB)
Katılan herkese çok teşekkürler. Bir başka aktivitede görüşmek üzere ;)
Hepinize tekrar selamlar, bugün epey yoğun bir trafik var blogumda
farkındayım :)
INETA Pro Hit'te katılım ile ilgili yaşadığımız sorunlar çerçevesinde yazımı
yazdıktan sonra birkaç mail aldım. Bazılarınız dert yanarken bazılarınız ise
"Evet zaten gelemeycektim" dedi. Her neyse konuyu daha fazla yılan hikayesine
çevirmek istemiyorum fakat ortada bir sorun olduğu belli. Level 300 üstü için biz
bu kadar katılım beklemiyorduk.
Bu sorunları bir sonraki etkinliğimizde yaşamamak adına aynı yazın Summer
Hit'te olduğu gibi tekrar Yıldız Teknik Üniversitesi
Oditoryum'unu rezerve ettik ve bir sonraki büyük etkinliğimizi orada
yapacağız. Bu çerçevede herhangi bir şekilde katılım sorunu olmayacaktır ve
kayıt olan HERKESİ kabul edeceğiz. Sizlere söz veriyorum tekrar
bir kayıt, eleme, çekiliş vs olmayacak!
11-12 Nisan olarak belirlediğimiz aktivitenin kaydını
şimdiden açıyorum. Daha etkinlik planımız belli değil! Zaten bir plan yapmak
için erken fakat Mart ayında Amerika'da Microsoft'un
MIX
konferansının olacağını da düşünürsek orada duyurulacak yeni ürünleri kesinlikle
plana almak istiyoruz. O nedenle tahminen planımız 23 Mart'ta belli olacaktır.
Silverlight 3 gibi ilginç konular olabilir :) Bilgiler gizli
olduğu için daha fazlasını paylaşma şansım yok.
INETA Next Hit olarak adlandırdığımız etkinliğe kayıt olmak için aşağıdaki
adresi kullanabilirsiniz;
http://daron.yondem.com/kayit/
Bu etkinlik ile ilgili esas duyurulara Mart ayında başlayacağız ama şimdiden
takviminize not almayı unutmayın.
Hepinize kolay gelsin.
Sanırım son attığımız maillerde bazı sorunlar olmuş. Bugün iki, üç kişiden
mail almadıklarına dair mailler aldım. Yarınki aktivitemiz için en son kayıt
olan ve güvenliğe adı verilecek olan liste aşağıdaki şekildedir. Bilginize.
A.Vehbi Olgaç, Abdullah Aslan, Abdullah Çakır, Abdülkadir Barlık, Adem Çınar, Ahmet Çubukçu, Ahmet Enes Dabalıoğlu, Ahmet Kabaoğlu, Ahmet Karaman, Ahmet Korkmaz, Alaattin Kızıl, Ali Ayen, Ali Çalı, Ali Derman Teloğlu, Ali Yıldız, Alistair Yaseen Bostanci, Alper Yıldırım, Alper Yücer, Altuğ Can Aldanmaz, Arda Yaraner, Armağan Bice, Aslı Ferah Kozalı, Aslı Gürel, Aydın Özmen, Aykut Gülenay, Aykut Önen, Aylin Sakar, Aysu Yıldırım, Batuhan Tosun, Bekir Yılmaz, Beytullah Taşkın, Bilgehan Ören, Birsen Tunç Yazar, Bora Akgün, Burak Dikici, Burak Hamza, Burhan Aras, Bünyamin Atik, Celal Bilgin, Cemal Polat, Cenk Gültekin, Cenk Parlak, Çağrı Çınar, Çetin Yılmaz, Davut Temel, Deniz İrgin, Deniz Sumbul, Denizer Yıldırım, Dinçer Uygun, Doğukan Erenel, Doruk Özer, Ebru Oğuzberk, Efe Çağın Kaptan, Ekrem Saydam, Elif Yıldırım, Elmas Adıyaman, Elvan Kahraman, Emin Balçiçek, Emrah Alper Aydın, Emrah Cetiner, Emrah Korkmaz, Emrah Sütcü, Emre Bayram, Emre Doğan, Emre Karakuş, Emre Kırnaz, Emre Koçyiğit, Enes Kurt, Enis Öztürk, Ercan Ermiş, Ercüment Türkeli, Erdem Ergin, Erdem Ergin, Erdem Kemer, Erdem Öztekin, Erdem Öztekin, Erdi Yilmaz, Erdinç Cırık, Eren Çetin, Eren Gençtürk, Eren Görmez, Erhan Kayar, Erhan Kocabaş, Erkan Akoğlu, Erkan Kilmen, Erkan Yanbul, Erman Güler, Ersin Öztürk, Ertugrul Akdag, Ertürk Erdağı, Esra Öncü, Eyup Ozen, Faruk Alkaya, Faruk Durak, Fatih Coşkun, Fatih Çetin, Fatih Gençaslan, Fatih Özkan, Fatih Şimşek, Fatma Akın, Fatma Demirci, Fikret Akın, Filiz Öztekin, Filiz Öztekin, Furkan Ekinci, Gafur Çınar, Gencay Karaman, Gonca Özmen, Gökay Gürsoy, Gökhan Bağcı, Gökhan Baş, Gökhan Baş, Gökhan Köşker, Gönül Taş, Gülsüm Şeyma Somuncu, Gürkan Keleş, Hadi Ytmail.Comolasığmaz, Hakan Aksoy, Hakan Baştürk, Hakan Bayısın, Hakan Coşar, Hakan Damar, Hakan Gündüz, Hakan Kaya, Halime Oral, Hanife Doğanay, Harun Taşdelen, Hasan Çetin, Hasan Kulak, Hasan Sarıtaş, Hasan Yılmaz, Hatice Aksoy, Hayati Bulat, Hayriye Dartar, Hicran Çokal, Hikmet Arat, Huseyin Yagiz, Hülya Aksu, Hüseyin Gözüküçük, Hüseyin Özcan, İbrahim Başer, İlker Çakırgöz, İnci Cabar, İsmail Tengirşek, İsmet Temur, Kadir Niyazi Açar, Kayhan İnalöz, Kazım Cesur, Kazım Çetin, Kemal Can Kara, Kemal Sayan, Kemal Serkan, Levent Kaya, Malik Ulu, Mansur Danış, Mehet Murat Huyut, Mehmet Ali Sahın, Mehmet Bakır Arvas, Mehmet Barış Günger, Mehmet Caner Ertüzün, Mehmet Çağrı Delice, Mehmet Çay, Mehmet Emin Çifci, Mehmet Emin Gürsoy, Mehmet Hacısalihoğlu, Mehmet Sarı, Mesut Kanberoğlu, Mesut Zerman, Metin Yavuz, Mithat Ercüment Eser, Muammer Hallaç, Muhammed Akgün, Muhammed Medeni Baykal, Muhammet İsmet Andaç, Muharrem Dönmez, Murat Akçura, Murat Çelik, Murat Durmuş, Murat Gökdemir, Murat Keske, Murat Koç, Murat Şahin, Murat Yıldız, Murat Yuksel, Mustafa Çağrı Toroslu, Mustafa Güven, Mustafa Mücahit Tozlu, Mustafa Sarıel, Mustafa Sarıtaş, Mustafa Torun, Mustafa Tosun, Mustafa Tosun, Mustafa Ülkü, Nagehan Oguz, Necaettin Keskin, Nergün Yalçınlar, Nesibe Erbaş, Nesim Tunç, Neslihan Ayaz, Neşi Sayan, Numan Ayhan, Oguz Kagan Yılmaz, Oğuz Erhan Eker, Oğuzhan Eren, Olcay Bayram, Olgun Subaşı, Onur Acun, Onur Ceryan, Onur Solhan, Onur Şimşek, Onur Ulcay, Orhan Aygün, Orhan Bekdemir, Orhan Odabaşı, Osman Aksu, Osman Pirci, Oytun Deniz, Ömer Arslan, Ömer Başoğlu, Ömer Çırak, Ömer Dinç, Ömer Ertuğ, Ömer Sağlam, Ömer Yamak, Özgür Çakmak, Özlem Koç, Pınar Ündeş, Ramazan Dağhan, Ramazan Eymur, Resul Güldü, Sabit Köse, Sabri Dizdar, Sadullah Keleş, Saffet Pamuk, Sahin Dagdelen, Saıful Parvez, Saim Türel, Salih Candan, Salih Selametoğlu, Saliha Can, Samet Sabır, Sami Yusuf, Sancak Özer, Sedat Doğan, Sedat Songültekin, Selçuk Aydoğan, Selçuk Ermaya, Selda Uzunhan, Selim Dilbaz, Semanur Konezoglu, Semi Kırcı, Serap Bircan, Serdar Çatalpınar, Serdar Selim Karaca, Serdar Sezgin, Serkan Akkaya, Serkan Baştutan, Serkan Selcuk, Sertaç Öz, Songül Tozan, Suat Çilingir, Suat Üstkan, Suat Üstkan, Süleyman Çan, Süleyman Günay, Tahsin İlhan Özçelik, Taner Başlı, Taner Yener Çolak, Tanju Canay, Tayfun Doğdaş, Tuba Çebi, Turan Ttürkmen, Ufuk Aytaş, Uğur Çelenk, Ümit Açıkgöz, Ümit Berber, Ümit Duman, Ümit İşgüder, Ümit İşgüder, Ümit Toptaş, Ümit Ünal, Volkan Cobanoglu, Volkan Kulikoğlu, Volkan Metin, Volkan Türk, Yalçın Kayan, Yasin Emecen, Yasin Özbey, Yılmaz Demir, Yunus Bel, Yunus Karadağ, Yusuf Arslan, Yusuf Karakaş, Yüksel Yılmaz, Yüzel Özkan, Zafer Düzen, Zafer Yılmaz, Zaferbaşoğlu, Zerrin Yılmaz, Zeynep Öztürk, Zuleyha Ozturk
Son günlerde INETA Professional Hit'in katılımı ile ilgili
ufak sorunlar oldu. Sizlerle gelişmeleri buradan ayrıca paylaşmak istiyorum.
Level 300 ve üstü seminerler dediğimiz için normal katılımın altında bir katılım
bekliyorduk fakat sanırım :) kimse beni dinlemedi ve 1600 kişilik kayıt aldık.
En son Summer Hit için de bu kaydı almıştık :)
Bu beklemediğimiz durum karşınızda salonumuz 150 kişilik olduğu için hemen
kolları sıvadık ve neler yapabiliriz diye düşünmeye başladık. Bu arada tabi ki
şu soruyu sorabilirsiniz "Neden 150 kişilik kayıt almadınız? Sınır
koysaydınız!" Maalesef bu gerçekçi bir davranış tarzı olmuyor çünkü 1600
kişi kayıt aldığımız Summer Hit'te anlık 350 kişilik katılım oldu. Yani aktivite
ücretsiz olduğu için kayıt olup gelmeyen çok oluyor ve biz de kimsenin hakkı
yensiz istemediğimiz için kayıtların ucunu açık bırakıyoruz. "O zaman neden
kayıt alıyorsunuz?" :) Güvenliğe liste verebilmek için.
Konuya dönelim; düşündük taşındık ve bir çözüm bulamadık. Ya etkinliği
erteleyecektik ya da yerini değiştirip Microsoft ofisinden alacaktık. Maalesef
son iki gün kala yer değiştirme şansımız da olmadığı için benim aklıma biraz
rahatsız edici radikal bir fikir geldi ve bu fikri şu an çok da beğenmiş
durumdayım :)
Şu ana kadar kaydolanlara tekrar bir mail atıp tekrar başka bir adresten
kaydolmalarını isteyelim dedim :) Böylece kaydolan 1600 kişiye "Gerçekten
katılıp katılmayacaklarını" aktiviteden iki gün önce soran ve eğer
katılacaklarsa başka bir adresten tekrar kaydolmalarını isteyen bir mail daha
gönderdik. Üzerine kayıt esnasında belirtilen cep telefonlarına da hemen birer
SMS yolladık ki insanlar maillerini kontrol etsin. Ortalama mailimizden 8 saat
sonra 300 kayıt aldık ve bu sefer "DUR" dedik :)
Şimdi de soracaksınız "neden 300?" Çünkü hala kaydolan
arkadaşlarımızdan "Ben sadece Pazar gelebilirim" veya "Ben sadece
Cumartesi gelebilirim" mailleri alıyorum. Tahminimce anlık 150-180 kişi
arası olacağız. Eğer tahminlerim yanlış çıkarsa ayakta kalanlar olacak :( Umarım
adetlerimize uygun şekilde bağdaş kurmaktan kimse çekinmez.
Böylece kesin katılım yapacak bir kesimi yakaladığımızı tahmin ediyorum fakat
bilemeyiz. Birçok mail aldım "Gerçekten kaydoldum ama gelemeyeceğim, üzgünüm"
yazan. Bakalım sonumuz ne olacak. :)
Talihli olarak niteleyebileceğimiz bu 300 kişiye biraz önce tekrar bir
mailing daha yaptık ve aktiviteye doğrudan davet ettik. Tüm bu aksaklıklar
nedeniyle herkesten çok özür diliyorum. Bu aslında bize şu mesajı verdi "500
kişiden düşük salonda toplu etkinlik yapmayın" :) Bundan sonra bu mesajı daha
dikkatlice aklımda tutacağım.
Gelen maillerde sorulan sorulara cevaben iki konudan daha bahsetmek
istiyorum. Birincisi etkinliğin videolarını kaydedeceğiz ve yayınlayacağız.
Yayınlamak için bize biraz zaman vermeniz yeterli. O videoları hazırlamak epey
uzun sürüyor. İkinci soru ise bir başka etkinlik olacak mı şeklindeydi. Yaza
kadar bir büyük etkinlik daha düzenlemeyi planlıyoruz ve bu sefer kesinlikle
kayıt sınırı olmayacak size en büyük salonu bulacağız :) Söz ;)
Hepinize ilginizden dolayı ÇOK teşekkür ediyorum.
Bundan iki hafta önce sevgili
basariligencler.com projesinin editörü İbrahim Eryiğit benimle iletişime
geçti ve bir röportaj talebinde bulundu. Onlara göre hem başarılı hem de
gençmişim :) Her ikisinin de göreceli konular olduğunu düşünürsek sanırım
buradan İbrahim'e ve ekibine teşekkür etmem gerekiyor. Hızlı bir röportaj
sürecinin sonunda İbrahim sağolsun benim netteki en ilginç fotoğraflarımı da
bularak bugün röportajı sitelerinde yayınlamış.
http://www.basariligencler.com/ineta-turkiye-baskani-daron-yondem-meslegimize-nankor-demek-nankorluk-olur.html
Tüm bu süreçteki yardımlarından dolayı İbrahim'e çok teşekkürler. Sizlere de
iyi okumalar :)
INETA tarafında 1 Nisan 2008 ile başlamış olduğum
Türkiye Başkanlığı görevini sizlere daha önceleri duyurmuştum. Bu görev
çerçevesinde ortalama bir önceki döneme göre yıllık bazda toplam etkinlik saat
süresini miktar olarak 80 katına çıkardık. Tüm bu yolculukta özellikle INETA Hit
serimiz çok tuttu ve Summer Hit ile başladığımız neredeyse tüm
HIT'lerimizde farklı sosyal topluluklarımızdan katılan konuşmacılar ile güzel
bir paylaşım ortamı sağladık.
Bir sonraki Hit'imiz Professional Hit'i birkaç gün önce
sizlere ayrıca duyurmuştum.
INETA Türkiye olarak ayrı bir sitemizin olmayışı ve MEA sitesini kullanmamız
bazen sitenin İngilizce olması nedeniyle kafa karışıklıklarına sebebiyet
verebiliyordu. Bu çerçevede minik bir müjde verebilirim, çok yakında INETA
Türkiye sitesi ile daha da büyük bir bomba şeklinde geliyoruz. Bürokratik
hazırlıklarımızı tamamladık, sıra teknik altyapıya geldi. Şimdilik duyurular
için benim blogu takip etmeye devam edin, INETA TR sitemizi açtığımızda hepinizi
oraya bekliyor olacağım. Aklımdakileri bir bilseniz :) Neyse sürpriz.
Bu yazıyı yazmamın aslında bir başka nedeni daha var; INETA MEA
tarafında organizasyon yapısında değişiklikler oldu. MEA sitesinden bu yapıya
ulaşabilirsiniz fakat yine İngilizce olacaktır. O nedenle ben buradan da
değişiklikleri dile getirmek istiyorum.
MEA Regional Manager olarak 1 Ocak 2009 tarihinden itibaren
Özgür Seyrek görev alıyor. Özgür'ü Türkiye içinde çok duymamış
olmanız normal :) zaten adı üzerinde MEA Regional Manager. 2009 yılında da INETA
Türkiye Başkanlığı görevini ben yürüteceğim. MEA tarafındaki
diğer rollerden biri Speaker Bureau Lead görevi. Türkiye
Başkanlığı'na ek olarak bu görevi de 2009
yılında ben üstleneceğim ve MEA (Ortadoğu Afrika) çapındaki konuşmacı bürosunu ben yöneteceğim.
Son olarak MEA tarafında Marketing Lead olarak görev almak
üzere de Aykut Taşdelen
ile beraber çalışacağız. Bu noktada sevgili Aykut hocamın işini kolaylaştırmak
adına görevindeki Marketing'in anlamı ile ilgili ufak bir
açıklama yapmak istiyorum. INETA tarafında Marketing'in anlamı bizim için
paylaşımı arttırmak şeklinde tanımlanıyor. Bu kapsamda sosyal topluluk sayısını
arttırmak, paylaşımı arttırmak Marketing olarak nitelendiriliyor. Aykut
hocamızın 2009'daki görevi de bu olacak.
Gördüğünüz üzere giderek ilerliyor ve büyüyoruz. Önümüzdeki dönemde
paylaşımın çok daha artacağını ve daha güzel bir yıl yaşayacağımızı tahmin etmek
zor değil.
Hepinizel en kısa zamanda görüşmek üzere ;)
Bu hafta sonu Microsoft'tan Tayfun Akçay ile beraber KKTC'de
Doğu Akdeniz
Üniversitesi'ni ziyaret ettik. Toplam üç gün süren bir aktivite serisi yaparak
faydalı olduğu kadar da eğlenceli bir ortam sağladığımızı tahmin ediyorum.
Oturumlar tamamen İngilizce olduğu için video kaydı almadık, fakat merak
etmeyin; en kısa zamanda aynı konuları içeren Türkiye'de de bir aktivite
düşünüyoruz.
Aktivitedeki tüm fotoğrafları aşağıdaki adresten ulaşabilirsiniz;
http://cid-8eca4439fd9a640f.skydrive.live.com/browse.aspx/INETA%20WeekEnd%20Cyprus
Son olarak özellikle Kıbrıs'taki tek MSP'miz sevgili Arif Görkem
Güngör'e, sevgili Hakan ve tüm ACM grubuna buradan selamlarımı
gönderiyorum, çok teşekkürler desteğiniz ve misafirperverliğiniz için.
Bugün sizlere SoThink'ten "Quicker for Silverlight"
ürününden bahsedeceğim. SoThink firması hali hazırda neredeyse tüm Flash
developer'ların bildiği ve özellikle Flash De-Compile araçları ile tanınan bir
yazılım şirketi. Silverlight'ın popülerliğinin giderek arttığını gördüğünü
tahmin ettiğim SoThink bunun bir sonucu olarak Silverlight için de hızlı bir
şekilde animasyonlu uygulamaların hazırlanması için ek bir araç çıkartmış.
Çok İlginç..
Nedir ilginç olan? İlginç olan SoThink'in çıkardığı bu aracın arayüzüne
baktığımızda tamamen Flash'ta animasyon yapar gibi animasyon hazırlayabilmemiz.
Aldığımız çıktı ise bir Silverlight projesi oluyor. Yani her zamanki gibi gidip
Flash'tan alışık olduğumuz yapıda KeyFrame'ler ekleyip Motion Tween'ler
yaratarak farklı TimeLine'lar ile ilerleyebiliyorsunuz.
İlginç olan kötü özellikler de var. Uygulama tamamen Silverlight tarafındaki
programlama işini JavaScript'e yıkıyor ve 2.0'da gelen .NET dillerinden
özel olarak tercih edilirse sadece C# kullanabiliyor. Bu durumda maalesef ki ben bu yazılımın Silverlight
geliştiricileri tarafından pek tercih edileceğini sanmıyorum. Diğer yandan
yaptığım denemelerde Silverlight'ın gücünün tam olarak kullanılamadığı ve FPS
miktarının düşük olduğunu gördüm.
Sonuç
Aşağıdaki adresten indirebileceğiniz "Quicker for Silverlight"'ı denemeye
değer mi? Karar sizin. Fakat uzun vadede bu ürünü takip etmekte fayda var çünkü
SoThink kendi alanında gerçekten başarılı bir yazılım şirketi belki bir gün bu
ürünleri de kullanılabilir bir hale gelir.
http://www.sothink.com/product/animation-maker-for-silverlight/index.htm
Uzun bir aradan sonra tekrar İstanbul'da güzel bir etkinlik ile
karşınızdayız. Ankara ve İzmir derken biraz İstanbul'u boşladığımızı kabul
ediyorum. Ama önümüzdeki dönemde bolca telafilerimiz olacak. Gelelim konumuza;
INETA Professional Hit!
İki günlük bir etkinlik dizisi ile bu sefer Microsoft binasında buluşuyoruz.
Fakat farklı bir şeyler var! Türkiye'de ilk defa tamamen Level 300 ve üstü
oturumlardan oluşan halka açık bir aktivite yapıyoruz. Gelin bu konuyu biraz
açıklığa kavuşturalım ve şu Level konusuna göz atalım.
- Level 100: Bahsi geçen konuya giriş ve genel anlatım
içerir. Katılımcıların oturumun konusu ile ilgili herhangi bir bilgi
birikimine sahip olmadıkları ön görülür.
- Level 200: Level 100 bilgisine sahip olunduğunu ve buna
ek olarak anlatılacak konu ile ilgili genel bir bilgi birikiminin
katılımcılarda olduğu var sayılır. Genelde bu oturumlarda anlatılan
teknolojilerin detayları ve kullanım alanları ile ilgili gerçek hayat
senaryoları işlenir.
- Level 300: Anlatılacak konu ile ilgili Level 200
bilgisine sahip olunduğu düşünülür. Bu oturumlarda bahsi geçen
teknolojilerin uç noktada kullanımına dair örnekler derinlemesine işlenir.
- Level 400: Bu oturumlar uzmanından uzmanına
oturumlardır. Anlatılan teknoloji ile ilgili en gelişmiş ve üst seviyeli
bilginin aktarıldığı bu oturumlar ürünlerin üst sınırlarını zorlayan
oturumlardır.
Gördüğünüz gibi normal şartlarda bizim INETA tarafındaki etkinliklerimiz
ağırlıklı olarak Level 100 ile Level 200 arasında dolaşıyor. Genel olarak
baktığımızda bu seviyenin üzerinde etkinliklerin eksikliğini sizler de
değerlendirme formlarında defalarca dile getirdiniz. INETA Professional Hit
tamamen uzmanlara hitap eden Level 300 ve Level 400 oturumlar içeriyor. Bu
kapsamda giriş seviyesi bir beklenti ile etkinliğe gelmemekte fayda var. Giriş
seviyesi için yakın zamanda bir etkinliğimiz daha olacak.
Program içeriğimiz ve oturumların seviyeleri şu şekilde;
24 Ocak
10.00-12.30 Silverlight ile Veri Uygulamaları -
Daron Yöndem - Level 300
13.00-16.00 ADO.NET Data Services -
Burak Selim Şenyurt - Level 300
16.30-18.00 SharePoint üzerinde özel kolon geliştirmek -
Nezih Tınas - Level 400
25 Ocak
10.00-12.30 Derinlerde C# 3.0 -
Burak Selim Şenyurt - Level 300
13.00-15.00 ASP.NET AJAX 4.0 -
Daron Yöndem - Level 300 15.30-18.00 Asp.Net Application ve Page LifeCycle
- Oğuz Yağmur - Level 300
Etkinlik Microsoft İstanbul ofisinde olacak. Adres şu şekilde; Bellevue Residence, Levent Mahallesi
Aydin Sokak, No: 7
Levent
Etkinliğe katılabilmeniz için aşağıdaki adresten kayıt olmanız gerekiyor.
http://daron.yondem.com/kayit/
Çok yakında giriş seviyesi etkinliklerde de görüşmek üzere.
Bir başka T-Shirt tasarımım ile karşınızdayım :) Bir önceki SilverMan T-Shirt'ünün
gördüğü ilgiden sonra tekstil sektörüne atılmasam da Windows 7'nin bende
yarattığı heyecanın bir yansıması olarak hemen kolları sıvadım ve aşağıdaki
gördüğünüz tasarımı yaptım.
 Windows 7 T-Shirt tasarımım.
Tasarımın önünde "I'm Running Windows 7" yazarken arka
yüzünden ise biraz kinayeli bir yaklaşım söz konusu. "Build 1337" de
aslında 1337'nin İngilizce jargonda leet yani "elite" olarak okunduğunu
hatırlamak gerek. Hemen altında da "Windows 7"nin betasında yer alan "for
testing purposes only" yerine :) "for best purposes only" diyerek aslında bu
işletim sistemini sadece iyi niyetli olarak kullanmanız gerektiğine dikkat
çekmek istedim :)
Benim T-Shirt'üm elime ulaştı ve sonraki etkinliklerde beni bu T-Shirt ile
görme ihtimaliniz çok yüksek ;) Tasarımın orijinal boyutları ile dosyalarını
aşağıdan indirebilirsiniz.
Tasarıma ait orijinal dosya - 14012009_2.rar (3,11 MB)
Bugünlerde bana sıkça gelen sorulardan biri Silverlight tarafından
uygulamanın çalıştığı adresin nasıl alınacağı ile ilgili oluyor. Aslında basit
bir şekilde Silvetlight'tan DOM'a çıkmanız bunun için yeterli olacaktır. Peki
bunu nasıl yaparız?
Silverlight içerisinden DOM'a çıkmak için yolculuğunuzun başlayacağını
namespace System.Windows.Browser namespace'i olacaktır. Bu NameSpace içerisinden
ister sayfadaki JavaScript metodlarına ulaşır ister sayfadaki HTML elementlerine
ulaşabilirsiniz.
[C#]
MessageBox.Show(System.Windows.Browser.HtmlPage.Document.DocumentUri.AbsoluteUri.ToString());
Yukarıda gördüğünüz kod Silverlight uygulamanızın çalıştığı sayfanın tam
yolunu verecektir. DocumentUri üzerinden giderek bu adrese ait
farklı bilgileri de alabilirsiniz.
Hepinize kolay gelsin.
Önümüzdeki hafta sonuna girerken Cuma gününden başlayarak KKTC'de
INETA Week-End ile tekrar karşınızda olacağız. 16-17-18 Ocak
tarihlerinde KKTC Doğu Akdeniz Üniversitesi'nde gerçekleştireceğimiz etkinlikteki tüm
oturumlar tamamen İngilizce olacak ve etkinlik halka da açık.
16 January 13.00-14.00 Opening Ceremony 14.00-15.00 DreamSpark
and Imagine Cup Launch 15.30-18.30 ASP.NET Dynamic Data
17 January 10.00-12.30 3D Business Applications with WPF 13.30-16.30 Multi-Core Parallel Programming
17.00-19.00 LAB: Parallelize Your .NET Applications
18 January 10.00-12.30 Online Business Applications with Silverlight 13.30-16.30 Programming for High Performance Computing
17.00-.19.00 Light up your data on the web with Silverlight!
Konuşmacı olarak ben, Microsoft'tan sevgili
Tayfun Akçay ve
KKTC'deki tek MSP'miz Görkem Güngör katılacak. Dolu dolu bir hafta sonu
olacağından eminim. KKTC'deki herkesi bekleriz ;)
Bu hafta sonu İzmir'deydik. Daha önce sizlere duyurmuş olduğum
INETA EGE HIT etkinliğini Dokuz Eylül Üniversitesi'nde gerçekleştirdik.
Katılımcı profili gerçekten muhteşemdi, hem Cumartesi hem de Pazar günü en ufak
bir oturumu bile kaçırmayın daimi bir kitlemiz vardı :) Benim için çok eğlenceli
ve sevindirici oldu diyebilirim. Her oturumda aldığım tepkiler çok güzeldi.
 INETA
Ege Hit başlangıcı.
Her zamanki gibi iki de anekdot yarattık; birincisi benim gülen surat
çizimimi görüp animasyon olarak "yağmur yağsın ve şemsiye açılsın" diyen
arkadaşımızdı :) Dikkatinizi çekerim gülen suratın ne yağmur ne de şemsiye ile
alakası yok ayrıca İzmir'de yağmur falan da yapmıyordu :) Her neyse... İkinci
anekdot ise buradan paylaşamayacağım hatta sanırım ömür boyu hiç
paylaşamayacağım bir şey :) Üzgünüm...
 INETA
Ege Hit sonu...
Organizasyondaki katkılarından dolayı sevgili İzmir MSP'lerimize buradan ÇOK
teşekkür ediyorum. Sevgili
Buğra, Murat,
Gülşah ve
Okan'a çok
teşekkürler. Etkinlik boyunca çekilen resimlerin orijinal boyutlu hallerine
buradan ulaşabilirsiniz. Ayrıca tüm oturumlardaki örneklere ait kodları da
aşağıdaki linkten bilgisayarınıza indirebilirsiniz.
Oturumlardaki örnek projeler - 11012009.rar (5,11 MB)
Silverlight 2.0 tarafında veritabanı erişimi için mecburen web servisleri
kullanmak zorundayız. Durum böyle olunca tek tek veritabanındaki işlemler için
ayrı web servisleri yazmak bir noktadan sonra işkenceye dönüşebiliyor.
Bugünlerde özellikle LINQ ve Entity Framework ile beraber data layer'larımızda
ciddi kolaylıklardan faydalanabiliyoruz fakat web servisleri tarafında
geldiğinde ise LINQ vs ile gelen nesneleri geri döndüren web servislerini tek
tek yazmak yine can sıkıcı bir hal alıyor.
Aslında tüm bu sorunları çözebilecek bir altyapı .NET Framework içerisinde
artık mevcut. ASP.NET Data Services adını verdiğimiz altyapı
ile beraber bir veritabanına erişimi doğrudan REST üzerinden yapabiliyorsunuz.
Peki nasıl?
İlk önce gelin ASP.NET Data Services sonuç olarak nasıl bir hizmet yaratıyor
ona bakalım. Bugün herhangi bir veritabanına farklı where sorguları ile
select'ler göndermek istesek bu sorgulardaki where cümleciklerini parametreli
hale getirmemiz ve bu parametreleri alarak uygun datayı döndüren web servisleri
yazmamız gerekiyor. Ancak bu şekilde Silverlight ile veritabanına
erişebiliyoruz. Farklı senaryolardan eğer sorgularınızın filtreleme şekilleri
değişirse bu sefer tekrar gidip uygun web servisini yazmak zorunda kalıyorsunuz.
Başka bir seçenek olarak where cümleciklerini parametre alan bir servis
yazılabilir fakat bu pek güvenli bir manzara olmaz.
Tüm bu problemleri çözmek için ASP.NET Data Services ile sorgularınızı
yazabileceğiniz özel bir syntax geliyor ve artık URL üzerinden sorgu
gönderebiliyoruz.
http://localhost:4351/WebDataService1.svc/Uruns(2)
Örneğin yukarıdaki gibi bir adrese gittiğimizde veritabanındaki Uruns
tablosunda ID'si 2 olan ürünün bilgilerini XML olarak almış oluyoruz.
[XML]
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<entry xml:base="http://localhost:4351/WebDataService1.svc/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<id>http://localhost:4351/WebDataService1.svc/Uruns(2)</id>
<title type="text"></title>
<updated>2009-01-11T22:18:06Z</updated>
<author>
<name />
</author>
<link rel="edit" title="Urun" href="Uruns(2)" />
<link rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Kategori" type="application/atom+xml;type=entry" title="Kategori" href="Uruns(2)/Kategori" />
<category term="SilverlightApplication17.Web.Urun" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Int32">2</d:ID>
<d:Adi>Ürün2</d:Adi>
<d:KategoriID
m:type="Edm.Int32">1</d:KategoriID>
</m:properties>
</content>
</entry>
Tahmin ettiğiniz üzere aslında bizim normal şartlarda yazdığımız web
servisleri de kısmen bu işi yapıyor. Yani bize XML ile istediğimiz veriyi
gönderiyoruz. Şimdi bir düşünelim, bu şekilde esnek olarak URL üzerinden farklı
sorgular gönderdiğimde bana istediğim veriyi XML ile sanki web servisinden sonuç
dönüyormuş gibi döndüren bir sistem aslında benim Silverlight tarafından
veritabanını sorgulamam için çok daha esnek bir yapı olmaz mı? Her farklı sorgu
için ayrı ayrı web servisleri yazmaktan kurtulmaz mıyım? Evet :) amaç da zaten
bu.
Tabi bu arada bir web servisinin çalışma şeklide ve sağladığı XML'lerin
snytax'ı ile buradaki biraz farklı. Konumuz dışında olsa da aradaki bu farkın
bilincinde olmakta fayda var.
Yapalım şu işi...
Gelin hızlı bir örnek ile ASP.NET Data Services yapısının kullanımını ve
Silverlight tarafındaki yansımalarını giriş seviyesine inceleyerek ilerleyelim.
İlk olarak yeni bir Silverlight projesi yaratıyor ve yanına da güzel bir ASP.NET
sitesi alıyoruz. ASP.NET sitemize hemen bir ADO.NET Data Service
dosyası
eklememiz gerekiyor. Bunu ASP.NET sitenize sağ tıklayarak "Add New Item" diyerek
gelen pencereden uygun dosyayı seçip yapabilirsiniz.
[VB]
Imports System.Data.Services
Imports System.Linq
Imports System.ServiceModel.Web
Public Class WebDataService1
Inherits DataService(Of
DataClasses1DataContext)
Public Shared Sub InitializeService(ByVal config As IDataServiceConfiguration)
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead)
End Sub
End Class
ADO.NET Data Service'i projenize eklediğinizde hemen karşınıza yukarıdaki
kodlar çıkacaktır. Koyu ile yazılı kısımları bizim elle eklememiz gerekiyor.
DataClasses1DataContext olarak adı geçen şey aslında
projemizdeki bir LINQ2SQL Classes dosyası. ADO.NET'in Data Servisleri üzerinden
hangi Entity'leri yayınlayacağını belirlememiz gerek. Bu nedenle aslında bir
data servisi yaratmadan önce ya LINQ2SQL DBML dosyanızı hazırlamanız ya da
Entity Framework tarafında Entity'lerinizi hazırlamanız gerekiyor. Yazımızın
konusu dışında olduğu için işin bu kısmına şimdilik değinmeyeceğim. Önemli olan
yarattığınız bu veri kaynağının yukarıdaki şekilde Data Servisi'nize aktarmanız.
Bir sonraki adımda ise veri kaynağındaki hangi Entity'lere ne şekilde erişim
hakları vereceğiniz. Yani bu data servislerini kullanarak insanlar sadece SELECT
mi yapabilecek, yoksa Update veya Delete işlemi de yapabilecekler mi ona karar
vermemiz gerekiyor. Bu noktada güvenlik açısından epey dikkatli olmak gerek. Ben
şimdilik AllRead diyerek sadece SELECT için veri kaynağındaki
tüm tabloları * işareti ile açtım.
Silverlight tarafındaki maceralar.
Servisimiz hazır olduğuna göre artık sıra geldi Silverlight tarafında bu
servisi kullanmaya. Başlangıç için normal bir web servisi kullanmaktan pek
farklı olmadığını söyleyebilirim. Silverlight projemize sağ tıklayarak "Add
Service Reference" diyoruz ve ADO.NET Data Service'imizin SVC dosyasının
adresini veriyoruz. Böylece gerekli istemci taraflı proxy yaratılmış oluyor.
Her zamanki gibi veri kaynağımızı kullanmadan önce servis üzerinden bir
bağlantı kopyası almamız gerekecektir. Normal şartlarda Silverlight ile
SoapClient sınıflarından kopya alırken bu sefer doğrudan DataContext
alacağız.
[VB]
Dim Veri As New ServiceReference1.DataClasses1DataContext(New Uri("http://localhost:4351/WebDataService1.svc/"))
DataContext'imizi alırken servisimizin tam yolunu da parametre olarak
veriyoruz. Böylece artık bu servis üzerindeki tüm veriye ulaşabiliriz. Sıra
geldi sorgularımızı yazmaya. Silverlight tarafında web servislerinin
kullanımında da olduğu üzere tüm veri trafiğinin asenkron ilerleyeceğini
hatırlarsak aslında sorgularımızı gönderip sonrasında ayrı bir event-listener
ile sonucu alacağımızı da tahmin etmek zor değil. ADO.NET Data Services
sorgularının URL üzerinden farklı bir syntax ile gittiğini görmüştük fakat
elimizde bir DataContext olduğuna göre geri gelen IQueryable nesneleri LINQ ile
sorgulayabiliyor olmamız gerekir. Söz konusu LINQ sorguları otomatik olarak Data
Services tarafına uygun şekilde çevrilerek gönderilecektir. Sözü daha fazla
uzatmadan kodumuzu inceleyelim.
[VB]
Dim Sorgu As System.Data.Services.Client.DataServiceQuery(Of ServiceReference1.Urun) = From gelenler In Veri.Uruns Where gelenler.ID = 2 Select gelenler
Sorgu.BeginExecute(New
AsyncCallback(AddressOf
Geldi), Sorgu)
[C#]
System.Data.Services.Client.DataServiceQuery<ServiceReference1.Urun> Sorgu =
(System.Data.Services.Client.DataServiceQuery<ServiceReference1.Urun>)
from gelenler in Veri.Uruns where gelenler.ID == 2 select gelenler;
Sorgu.BeginExecute(new
AsyncCallback(Geldi), Sorgu);
Yukarıdaki kodlar bir sorgunun sunucu tarafına gönderilmesini sağlayacak olan
kodlar. Sorgumuzu ilk satırda standart LINQ sorgusu olarak yazıyoruz fakat
unutmayın ki burada bazı sınırlamalar var. ADO.NET Data Services sorgularında
tüm keyword'leri kullanmak mümkün olmuyor. O nedenle eğer buradaki LINQ
sorgularında Take vs gibi bazı keyword'leri kullanırsanız Visual Studio hata
verecektir.
Yazdığımız sorguyu bir DataSerivceQuery değişkenine
eşitliyoruz ve Query nesnemizi yaratırken de geriye ne tür bir
nesne döneceğini yine servis üzerinden gelen nesne tanımı ile belirtiyoruz.
Artık sorgumuz hazır olduğuna göre BeginExecute ile
çalıştırabiliriz. Fakat bu noktada da iki parametreye ihtiyacımız var; birincisi
bu sorgu tamamlandığında hangi event çalıştırılacak? Yani bir Callback lazım
bize. Asenkron bir Callback yaratarak ilerliyoruz. İkinci
parametre ise sorgunun kendisi. Böylece CallBack çalıştığında buradaki sorgunun
state'i de geri dönecek.
[VB]
Sub Geldi(ByVal ar As IAsyncResult)
Dim Sorgu As System.Data.Services.Client.DataServiceQuery(Of ServiceReference1.Urun) = ar.AsyncState
Dim result = Sorgu.EndExecute(ar)
MessageBox.Show(result.SingleOrDefault.Adi)
End Sub
[C#]
void Geldi(IAsyncResult ar)
{
System.Data.Services.Client.DataServiceQuery<ServiceReference1.Urun> Sorgu =
(System.Data.Services.Client.DataServiceQuery<ServiceReference1.Urun>)ar.AsyncState;
var result = Sorgu.EndExecute(ar);
MessageBox.Show(result.SingleOrDefault().Adi);
}
Geldi adındaki asenkron callback'imiz çalıştığında hemen kendisine parametre
olarak gelen Result'ın için AsyncState
üzerinden Sorgu değişkenimizi alıyoruz. Artık sorgu
tamamlandığında göre çalışma işlemini de sonlandırıp sonucu almak gerek.
EndExecute metoduna tekrar Callback'e gelen parametreyi verip sonucun
bir değişkene aktarılmasını sağlıyoruz ve aldığımız değişken üzerinden
istediğimiz veriye ulaşabiliyoruz.
İşte bu kadar...
Data Services yapısı ile Silverlight tarafındaki kodlamanın çok
kolaylaştığını söylemek pek doğru olmaz. Elimizde veriyi sağlayan hazır bir web
servisi olsaydı çok daha rahat bir kodlama ortamına sahip olabilirdik fakat Data
Services bize web servislerine dokunmadan tek bir altyapıya bağlanarak
istediğimiz sorguları çalışma zamanında oluşturma şansı tanıyor. Tabi bu
sorgular sadece SELECT sorguları olmak zorunda değil, yeri geldiğinde Update,
Delete ve Insert de yapabiliriz. Bu makalemizde giriş seviyesinde kalacağımız
için şimdilik diğer işlemlere pek dokunmayacağız.
Hepinize kolay gelsin.
Bu yazımızda Silverlight 2.0 içerisinde maskeleme (clip) işlemlerine göz
atacağız. İlk olarak basit bir maskeleme işleminin XAML içerisinde nasıl
yapıldığına baktıktan sonra bu maskeleri nasıl anime edebileceğimize ve
programatik yoldan ulaşımına değineceğiz.
Bir maske yaratalım!
Herhangi bir nesneye maske aktarmak demek aslında o nesnenin Clip özelliğine
uygun bir şekil aktarmak demektir. Elinizde var olan bir geometri nesnesini
alarak bir element'in Clip özelliğine verdiğiniz anda artık söz konusu Geometri
nesnesi bir maske görevi görür. Expression Blend içerisinde baktığınızda
maskeler nesnelerin birer Property'sine atandığı için ayrı birer obje olarak
arayüzde gözükmez.
 Expression Blend içerisinde maskelenmeye hazır kontroller.
Yukarıdaki ekran görüntüsünde de görebileceğiniz üzere sahnede bir Image ve
bir de Ellipse nesnesi bulunuyor. Bir sonraki adımda amacımız bu Ellipse
nesnesini Image için bir maske haline getirmek. Yapacağımız işlem bu iki nesneyi
fare ile seçip "Objects and Timeline" kısmında sağ tıklayıp "Path / Make
Clipping Path" komutunu vermek. Böylece söz konusu Ellipse artık
Image'in Clip özelliğine bir geometri olarak aktarılacak ve ortada Ellipse diye
bir nesne kalmayacak.
 Maskelenmiş Image kontrolümüz karşınızda.
Artık kontrolümüzü maskeledik ve Ellipse diye bir nesne kalmadı peki
arkaplanda XAML tarafında neler oldu? Gelin Blend'in bizim için yarattığı XAML
kodunu bir detaylıca inceleyelim.
[XAML]
<Image Margin="25.032,27,84.032,54.842" Source="1080366_88011245.jpg" Stretch="Fill"
Clip="M258.5,130 C258.5,166.17465 212.60919,195.5 156,195.5 C99.390816,195.5 53.5,166.17465 53.5,130 C53.5,93.825348 99.390816,64.5 156,64.5 C212.60919,64.5 258.5,93.825348 258.5,130 z"/>
Gördüğünüz gibi Image nesnesinin uzun bir Clip datası var. Bu data bizim bir
önceki adımda yarattığımız Ellipse'in ta kendisi. Aslında bu kodu bu şekilde
yazmak yerine daha okunaklı bir şekilde de yazabilirdik. Nasıl mı?
[XAML]
<Image Margin="7.968,-68,101.032,0" Source="1080366_88011245.jpg" Stretch="Fill" VerticalAlignment="Top" Height="218">
<Image.Clip>
<EllipseGeometry Center="200,100" RadiusX="90" RadiusY="60" />
</Image.Clip>
</Image>
Peki ne değişti? Nesne basında Clip vermiş olduk. Image nesnesinin Clip
özelliğine doğrudan koordinatları girmek yerine ayrı bir element vermeye karar
verdik ve bu nedenle de Image.Clip tagları açarak içerisine bir Geometry nesnesi
yerleştirdik. EllipseGeometry nesnesi gibi GeometryGroup,
LineGeometry, PathGeometry nesneleri de
mevcut. Bizdeki örnekte EllipseGeometry'nin Center
özelliği maskelenen Image nesnesinin merkez noktasına göre
maskenin ne kadar uzaklıkta olacağına dair X ve Y değerlerini verirken RadiusX
ve RadiusY'de yatay ve dikey olarak Ellipse'in yarıçapını tanımlıyor. Peki bu
iki metod arasındaki diğer farklar nelerdir? Gelin olayın animasyon kısmına bir
bakalım.
Maskelere animasyon katalım....
Herhangi bir nesnenin maskesine animasyon verebilmek için Expression Blend
içerisinde animasyon modunda sol taraftaki araç çubuğundan Selection
aracı yerine "Direct Selection" aracını kullanmalısınız. Söz
konusu aracı seçtiğiniz anda seçili nesnenin maskesine ait tanımlı noktaları
ekranda görebilirsiniz. Böylece rahatlıkla KeyFrame'ler yaratarak noktaların
pozisyonlarını değiştirebilir ve maskeyi anime edebilirsiniz.
 Maskemize animasyon verirken.
Biz örneğimizde maskedeki tüm noktaları toplu seçerek bir Ellipse şekliden
tüm maskenin pozisyonunu değiştiren bir animasyon hazırlıyoruz. Böylece sanki
bir ışık ile resme bakılıyormuş gibi resmin üzerinde geziliyor görüntüsü
yaratıyoruz. Gelin Blend'in bizim için yarattığı XAML koduna göz atalım.
[XAML]
<Storyboard x:Name="Storyboard1">
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.StartPoint)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="258.5,130"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="218.937328102718,129.064332728402"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="258.5,166.174652099609"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="218.937328102718,165.238984828011"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="212.609191894531,195.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="173.046519997249,194.564332728402"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="156,195.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="116.437328102718,194.564332728402"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="99.3908157348633,195.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="59.8281438375813,194.564332728402"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="53.5,166.174652099609"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="13.937328102718,165.238984828011"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="53.5,130"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="13.937328102718,129.064332728402"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="53.5,93.8253479003906"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="13.937328102718,92.8896806287922"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="99.3908157348633,64.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="59.8281438375813,63.5643327284016"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="156,64.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="116.437328102718,63.5643327284016"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="212.609191894531,64.5"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="173.046519997249,63.5643327284016"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="258.5,93.8253479003906"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="218.937328102718,92.8896806287922"/>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="258.5,130"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="218.937328102718,129.064332728402"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
Animasyonun kodu gördüğünüz gibi epey uzun. Aslında Blend kendi Clip'ini
noktalardan yarattığı için mecburen bu noktaları tek tek anime ederek noktaların
pozisyonlarını değiştirmek zorunda kalıyor. Bu esnada bizim Image'in XAML
kodlarına bakarsan zaten minik bir değişiklik de dikkatimizi çekiyor.
[XAML]
<Image Margin="57,73.921,52,8.079" Source="1080366_88011245.jpg" Stretch="Fill" x:Name="image">
<Image.Clip>
<PathGeometry>
<PathFigure IsClosed="True" StartPoint="258.5,130">
<BezierSegment Point1="258.5,166.174652099609" Point2="212.609191894531,195.5" Point3="156,195.5"/>
<BezierSegment Point1="99.3908157348633,195.5" Point2="53.5,166.174652099609" Point3="53.5,130"/>
<BezierSegment Point1="53.5,93.8253479003906" Point2="99.3908157348633,64.5" Point3="156,64.5"/>
<BezierSegment Point1="212.609191894531,64.5" Point2="258.5,93.8253479003906" Point3="258.5,130"/>
</PathFigure>
</PathGeometry>
</Image.Clip>
</Image>
Söz konusu Clip'in içindeki noktaları anime edebilmek için Blend de kısmen
bizim taktiğe geri dönmüş ve bir PathGeometry yerleştirmiş. Oysa biz zamanında
Ellipse koymuştuk :) Neden doğrudan o esnada EllipseGeometry
koymadın? diye Blend'e sorarsak eminim cevabı basit olacaktır. "Nereden
bilebilirim ki bu noktaları ayrı ayrı anime etmeyeceğinizi?" Aslında Blend
haklı. Blend her ihtimali düşünmek zorunda çünkü o bir GUI :) Oysa biz kendi
örneğimizde maske olarak Ellipse'in şeklini değiştirmeyeceğiz, sadece konumunu
değiştireceğiz o nedenle bu sistem bize çok da uygun değil.
Yukarıdaki PointAnimation taglarına bakarsan tek tek Image
nesnesinin Clip özelliğindeki değerin alınıp bu değerdeki
noktaların Index numarası verilerek bulunduğunu ve pozisyonlarının
değiştirildiğini görebilirsiniz. Performans açısından bir sıkıntısı olmasa da
oluşan kodun okunabilirliliği çok zayıf olmakla beraber bu gibi bir Clip
nesnesinin programatik olarak anime edilmesi de neredeyse imkansız. C# veya VB
kodu ile tek tek bu noktaları bulup anime etmek işkenceden farksız olacaktır.
Peki ya bizim teknikle yaparsak?
Bizim esas istediğimiz maskenin konumunun değişmesiydi. Daha önceki
kodlarımızda bir EllipseGeometry'yi maske olarak verebilmiştik. Bu
EllipseGeometry nesnesinin Center özelliği maskenin konumunu belirliyordu. Bu
durumda bizim kodumuzda bu özelliklerin anime edilmesi yeterli olacaktır. Fakat
eğer Blend içerisinde bu animasyonu yapacak olursanız bizim EllipseGeometry'yi
ısrarlı bir şekilde yukarıdaki gibi bir PathGeometry'ye
çevirecek ve yine aynı animasyon kodunu üretecektir. Bu durumda bizim de
programatik olarak bu maskeyi anime etmemiz yine zorlaşacaktır.
Sonuç olarak eğer bir nesnenin maskesinin pozisyonunu çok uğraşmadan kod ile
anime edebilmek istiyorsanız Blend'in arayüzünden anime etmemeniz gerekiyor.
Programatik olarak maskeye erişmek...
Bir nesnenin maskesine programatik olarak erişmek için söz konusu nesnenin
Clip özelliğini alıp uygu Geometry tipine cast edebilirsiniz. Sonrasında
elinizde Geometry nesnesi ile ilgilenmeniz yeterli olacaktır. Oysa bir diğer
seçenek de XAML içerisinde bu Geometry nesnesine el ile bir isim vermektir.
[XAML]
<Image Margin="7.968,-68,101.032,0" Source="1080366_88011245.jpg" Stretch="Fill" VerticalAlignment="Top" Height="218">
<Image.Clip>
<EllipseGeometry
x:Name="Maskesi" Center="200,100" RadiusX="90" RadiusY="60" />
</Image.Clip>
</Image>
Gördüğünüz gibi basit bir şekilde bizim EllipseGeometry nesnesine bir isim
verdik. Artık kod tarafında bu isim ile EllipseGeometry'ye
ulaşabilir ve Center veya RadiusX ve RadiusY
özelliklerini değiştirebiliriz.
[VB]
Maskesi.Center = New Point(200, 200)
Böylece tamamen kod ile bu maskeyi anime etmek istediğinizde de rahatlıkla bu
noktayı anime ederek maskenin pozisyonunun değiştiği bir animasyon
üretebilirsiniz. Örnek bir kodu aşağıda inceleyebilirsiniz.
[VB]
Dim DBL As New PointAnimation
DBL.From = New
Point(100, 100)
DBL.To = New
Point(200, 200)
DBL.Duration = New TimeSpan(0, 0, 2)
Storyboard.SetTarget(DBL,
Maskesi)
Storyboard.SetTargetProperty(DBL, New PropertyPath(EllipseGeometry.CenterProperty))
Dim SB As New Storyboard
SB.Children.Add(DBL)
SB.Begin()
[C#]
PointAnimation DBL = new PointAnimation();
DBL.From = new Point(100, 100);
DBL.To = new Point(200, 200);
DBL.Duration = new TimeSpan(0, 0, 2);
Storyboard.SetTarget(DBL, Maskesi);
Storyboard.SetTargetProperty(DBL, new PropertyPath(EllipseGeometry.CenterProperty));
Storyboard SB = new Storyboard();
SB.Children.Add(DBL);
SB.Begin();
Eğer bu animasyonu XAML tarafında temiz olarak yazmak isterseniz aslında
pratik bir şekilde elle de yazabilirsiniz.
[XAML]
<Storyboard x:Name="Storyboard1">
<PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Maskesi" Storyboard.TargetProperty="(EllipseGeometry.Center)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="100,100"/>
<SplinePointKeyFrame KeyTime="00:00:01" Value="200,200"/>
</PointAnimationUsingKeyFrames>
</Storyboard>
Animasyonumuz doğrudan Maskesi adındaki EllipseGeometry'yi
hedef alarak onun Center property'sini anime ediyor.
Unutmayın ki bizim örneğimizde böyle bir optimizasyon yapabilmemizin nedeni
maskenin sadece pozisyonunu değiştirmek istememiz. Eğer maskedeki her bir
noktanın konumunu ayrı ayrı birbirinden bağımsız olarak anime etmek isterseniz
Blend'in yaptığı teknikten farklı bir seçeneğiniz zaten yok.
Hepinize kolay gelsin.
Silverlight Toolkit içerisindeki kontrollerin açık kaynak kodları ile beraber
dağıtıldığını zaten biliyoruz. Microsoft'tan bağımsız olarak ilerleyen bu
projeye ek olarak Silverlight 2'nin dahili gelen MS kontrollerinin de kaynak
kodları açıldı! Artık Silverlight 2 Runtime içerisinde bulunan aşağıdaki
kontrollerin kaynak kodlarını bilgisayarınıza indirip inceleyebilirsiniz.
ButtonBase,
Button,
HyperlinkButton,
CheckBox,
RadioButton,
CheckBox,
ToogleButton,
RepeatButton,
RangeBase,
Slider,
ScrollBar,
ProgressBar,
Calendar,
DataGrid,
DatePicker,
GridSplitter,
TabControl
Tüm kaynak kodlarını aşağıdaki adresten indirebilirsiniz;
http://www.microsoft.com/downloads/details.aspx?FamilyID=EB83ED4C-AC85-4DE9-8395-285628EE2254&displaylang=en
Bugün İstanbul Ticaret Üniversitesi'ndeydim. Üniversiteden
Imagine Cup'a katılmak üzere hazırlanan bir ekibin isteği
üzerine WPF ve Silverlight konulu ikişer saatlik seminerler yapıp sonrasında da
ekiple bir odaya kapandık :) Projelerinde karşılaştıkları bazı esaslı sorunlarla
ilgili çözümler ürettikten sonra günü sonlandırdık.
 İstanbul Ticaret Üniversitesi, Silverlight ve WPF Seminerleri
Organizasyondaki katkısından dolayı MSP Bilgehan Gürünlü ve Kemal Can Kara'ya
buradan çok teşekkür ediyorum. Ekip gerçekten çok heyecanlı ve en önemlisi
bilgiliydi. Umarım Silverlight ve WPF dünyasında aranıza tasarımcılar katmayı da
unutmaz ve Imagine Cup'da başarılı olursunuz ;)
Hepinize sevgiler.
Silverlight içerisinde otomatik olarak farenin çift tıklamasını algılayacak
bir sistem bulunmuyor. Çok ciddi bir eksik gibi gözükmese de aslında özellikle
iş uygulamaları hazırlarken bu eksik can sıkabiliyor. Aslında bu eksiği
gidermenin çok kolay bir yolu var. Çift tıklama sistemi entegre etmek
istediğiniz bir kontrol normal tıklama durumunu kontrol ederek bir önceki normal
tıklama ile aradaki süreyi ve bir önceki tıklama ile şu anki tıklamanın
pozisyonlarını kontrol etmeniz yeterli olacaktır.
[VB]
Dim SonKonum As Point
Dim SonTik As Date
Private Sub Page_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
If e.GetPosition(Me).X < SonKonum.X + 10 And e.GetPosition(Me).X > SonKonum.X - 10 Then
If e.GetPosition(Me).Y < SonKonum.Y + 10 And e.GetPosition(Me).Y > SonKonum.Y - 10 Then
If DateDiff(DateInterval.Second, SonTik, Now) < 1 Then
MessageBox.Show("HO")
End If
End If
End If
SonKonum = e.GetPosition(Me)
SonTik = Now
End Sub
Yukarıdaki kod içerisinde de görebileceğiniz üzere ilk olarak bir önceki
tıklama bilgilerini saklamak üzere bir Date bir de
Point değişkenimizi global olarak tanımlıyoruz. Bu değişkenlerin
sürekli en son tıklamaya ait konum ve zaman bilgilerini saklayacak. Sonrasında
MouseLeftButtonDown event-listener'ı içerisinde bir önceki tıklama ile şu anki
tıklamanın koordinatlarını karşılaştırıyoruz. Kullanıcı tabi ki biraz fareyi
kaydırmış olabilir o nedenle yaklaşık 20 piksellik bir kayma payı verebiliriz.
Eğer yeni gelen tıklamanın koordinatları bir önceki ile aynı ise bu sefer de
ikinci tıklama anı ile bir önceki tıklama arasında geçen süreyi hesaplıyoruz.
Süre bir saniyenin altında ise büyük ihtimal ile bir çift tıklama gerçekleşmiş
demektir. Bizim örneğimizde basit bir MessageBox gösteriyoruz, sizin
kodlarınızda tabi ki farklı işlemler yapılacaktır.
Tüm bu kontrollerin sonucu olumlu ve olumsuz olsun, en sonunda da Son
Tıklama'ya ait bilgileri saklayacak olan değişkenlerimize yeni tıklamanın
bilgilerini aktarmayı unutmuyoruz ki bir sonraki tıklamada bu bilgileri "bir
önceki" tıklama bilgileri başlığı ile incelenebilsin.
Hepinize kolay gelsin.
Silverlight kullanılan web sitelerin artış ile aslında kullanıcılara da
Silverlight yükletme konusunda ısrar giderek artıyor :) Bu konunun bir ısrar
olmaması ve kullanıcıların gönül rahatlığı ile Silverlight Runtime'ını
yükleyebilmeleri için aslında yükleme sürecinin öncesindeki kullanıcı deneyimi
çok önemli.
Eğer istemcide Silverlight yüklü değil ise sizin OBJECT tagları ile sayfaya
yerleştirdiğiniz uygulama gösterilmeyecektir. Bunun yerine OBJECT tagları
arasındaki HTML kodu kullanıcıya gösterilir. Visual Studio ve Expression Blend
ile yeni bir proje yarattığınızda söz konusu HTML kodu varsayılan şekli ile
aşağıdaki gibi gelir.
[HTML]
<object data="data:application/x-silverlight-2,"
type="application/x-silverlight-2"
width="100%" height="100%">
<param name="source"
value="ClientBin/Carousel.xap"/>
<param name="onerror"
value="onSilverlightError"
/>
<param name="background"
value="white" />
<param name="minRuntimeVersion"
value="2.0.31005.0"
/>
<param name="autoUpgrade"
value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style: none"/>
</a>
</object>
Yukarıdaki OBJECT tagları arasında renkli olarak gördüğümüz kısım sadece
Silverlight yüklü olmadığında gösterilecektir. Bu kısıma istediğiniz HTML kodunu
koyabilirsiniz. Buradaki standart link Silverlight'ın Microsoft sitesinde
yükleme sayfasına yönlendirirken diğeri de standart "Install Silverlight"
görselini gösterir.
 Standart Silverlight Yükleme mesajı.
Kendi özel "Silverlight Yükle" görselinizi ve mesajınızı hazırlarken
kullanıcıları korkutup kaçırmamak adına sizlere birkaç tavsiyem olacak.
- İnsanlara "Silverlight Yükle" derken neden yüklemelerini istediğinizi
belirtin.
- Kullanıcıların yüklemeden önce de sitenizin nasıl bir şey olduğunu
görmeleri sağlayın, merak uyandırın. Özetle Silverlight yüklerlerse nasıl
bir şeyle karşılaşacaklarını görsünler ki yüklemeye daha sıcak baksınlar.
Aşağıda bulabileceğiniz örnekte Silverlight ile çalışan bir sitenin
Silverlight yüklü olmadığında da nasıl gösterildiğini inceleyebilirsiniz.
Standart "Install Silverlight" görseli yerine böyle bir deneyim çok daha çekici
olacaktır.
 Örnek Silverlight Yükleme Ekranı
Hepinize kolay gelsin.
Özellikle RIA uygulamalarındaki en büyük sorunlardan biri anlık internet bağlantısı kesintilerinde sayfanın bir daha geri ulaşılamayacak şekilde ekrandan kaybolması
veya farklı hataların ortaya çıkarak geri dönüşü imkansız hale getirmesidir. Bu hoş olmayan durumu artık Internet Explorer 8.0 ile beraber çözebiliyoruz. IE 8.0 içerisinde
navigtor.offline nesnesi ile istemci tarafında internet bağlantısının o an için olup olmadığı kontrol edebildiğimiz gibi internet bağlantısı ile ilgili değişiklikleri algılayacak event-handler tanımlamaları da yapabiliyoruz. Bu kolaylıklar ile artık AJAX
veya Silverlight uygulamalarının istemci tarafındaki kesintileri algılayarak uygun bir şekilde kullanıcıyı
uyarmaları mümkün. Hatta belki de internet bağlantısının koptuğunu algılayan
uygulama veriyi DOMStorage'a saklayıp bir sonraki çalıştığında sunucuya
gönderebilir. Minik bir örnek ile bu işlemleri nasıl yapabileceğimize göz atalım.
[HTML]
<body
ononline="VarMi();"
onoffline="VarMi();">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div id="icerik">
</div>
<input onclick="VarMi();" id="Button1" type="button" value="button" />
</form>
</body>
Yukarıdaki HTML kodu içerisinde özellikle koyu yazılı noktalara dikkat etmemiz gerekiyor. Birazdan yazacağımız
VarMi adındaki JavaScript fonksiyonumuz istemcide internet bağlantısı olup olmadığını kontrol edecek. Fakat hangi durumlarda bu kontrolü yapacağız? İlk olarak söz konusu fonksiyonumuzu sayfamızda bir düğmeye bağladık. Böylece istediğimiz zaman tıklayarak internet bağlantısı olup olmadığını öğrenebiliriz. Diğer yandan istemcide internet bağlantısı koptuğunda veya internet bağlantısı geldiğinde de
VarMi fonksiyonumuzun çalışarak gerekli değişiklikleri yapmasını istiyoruz. O nedenle body’nin
ononline ve onoffline özelliklerine de söz konusu fonksiyonumuzun adını yazıyoruz. Böylece
online durumunda yani internet bağlantısı geldiğinde veya
onoffline durumunda yani internet bağlantısı kesildiğinde de anında
VarMi fonksiyonumuz çalıştırılacak. Gelelim şimdi de VarMi fonksiyonumuzu yazmaya.
[JScript]
function VarMi() {
if (window.navigator.onLine) {
$get("icerik").innerHTML = "İnternet Var";
}
else {
$get("icerik").innerHTML = "İnternet YOK";
};
}
Aslında kod çok basit. navigator.onLine metodu bize geriye bir
Boolean değeri döndürüyor. Eğer tarayıcıda o an internet
bağlantısı varsa sayfadaki bir DIV içerisine uygun uyarı mesajını yazıyoruz.
Aynı şekilde eğer bağlantı yoksa bu sefer de farklı bir uyarı mesajı yazıyoruz.
Siz örneklerinizde bu durumlara göre farklı işlemler yapabilirsiniz. Böylece
hazırladığınız web sitesi yeri geldiğinde belki bazı işlemleri bir süreliğine
sunucudan bağımsız olarak da yapabilir ve nasıl çalışacağına internet
bağlantısının durumuna bakarak kendisi karar verebilirim.
Hepinize kolay gelsin...
Carousel kontrolleri son dönemin modası diyebiliriz. Çoğu yazılımın
arayüzünde Carousel kontrolleri görmeye başladık. Özellikle web sitelerinde de
neredeyse RIA denildiği anda bir yere bir Carousel konulması gibi bir moda da
mevcut. Bu çerçevede Silverlight 2 uygulamalarınızda Carousel yapılarından
faydalanmak isterseniz herşeyi sıfırdan yazmanıza gerek yok. Bu yazımda sizlere
açık kaynak kodu ile dağıtılan hazır bir Carousel kontrolünü tanıtacağım.
Coolmenu Carousel kontrolü
İlk olarak gelin kullanacağımız kontrolü kendi web sitesinden bir
bilgisayarımıza indirelim. Aşağıdaki adresten indirebileceğin kontrolün tüm
kaynak kodları ile alıp inceleme şansınız var. Biz şimdilik RC0 için hazırlanmış
olan paketi alarak içerisinde Coolmenu.DLL dosyasını kullanacağız. Yani kaynak
kodları ile uğraşmayacak doğrudan kontrolün Compile edilmiş halini projelerimize
entegre edeceğiz.
http://pagebrooks.com/archive/2008/08/21/coolmenu-a-silverlight-menu-control.aspx
Projemize Carousel ekleyelim!
Projemizde Coolmenu Carousel kontrolünü kullanabilmek için ilk olarak
download paketinden Coolmenu.Dll dosyasına Silverlight projemize referans olarak
eklemeliyiz. Sonrasında XAML tarafında söz konusu kontrolü sayfaya koyabilmemiz
için gerekli namespace tanımlarını yapmamız şart.
[XAML]
<UserControl x:Class="SilverlightApplication8.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300"
xmlns:SilverlightContrib_Controls="clr-namespace:SilverlightContrib.Controls;assembly=CoolMenu">
<Grid x:Name="LayoutRoot" Background="White">
<SilverlightContrib_Controls:CoolMenu x:Name="Carousel"/>
</Grid>
</UserControl>
Yukarıdaki XAML kodunu incelediğiniz özellikle dikkat etmemiz gereken aslında
iki nokta var. Bunlardan ilki xmlns tanımımız. SilverlightContrib_Controls
adında tanımladığımız yeni XML namespace'imiz doğrudan Coolmenu
assembly'sini hedefliyor. Böylece söz konusu assembly içerisindeki tüm kontrollü
XAML içerisinde kullanabileceğiz. Bir sonraki adımda da tanımladığımız
NameSpace'i kullanarak CoolMenu kontrolünden bir adet ekrana
yerleştirerek adını da Carousel olarak tanımlıyoruz. Bu
aşamadan sonrası için kod tarafına geçmemiz ve bu Carousel içerisinde
gösterilecek öğeleri tanımlamamız gerek.
[VB]
Dim Foto As New Image
Foto.Source = New Imaging.BitmapImage(New Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute))
Carousel.Items.Add(New SilverlightContrib.Controls.CoolMenuItem() With {.Content = Foto})
Foto = New Image
Foto.Source = New Imaging.BitmapImage(New Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute))
Carousel.Items.Add(New SilverlightContrib.Controls.CoolMenuItem() With {.Content = Foto})
Foto = New Image
Foto.Source = New Imaging.BitmapImage(New Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute))
Carousel.Items.Add(New SilverlightContrib.Controls.CoolMenuItem() With {.Content = Foto})
[C#]
Image Foto = new Image();
Foto.Source = new Imaging.BitmapImage(new Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute));
Carousel.Items.Add(new SilverlightContrib.Controls.CoolMenuItem { Content = Foto });
Foto = new Image();
Foto.Source = new Imaging.BitmapImage(new Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute));
Carousel.Items.Add(new SilverlightContrib.Controls.CoolMenuItem { Content = Foto });
Foto = new Image();
Foto.Source = new Imaging.BitmapImage(new Uri("http://daron.yondem.com/tr/images/vesikalik2.png", UriKind.Absolute));
Carousel.Items.Add(new SilverlightContrib.Controls.CoolMenuItem { Content = Foto });
Örnek kodlarımız içerisinde sürekli yeni Image nesneleri yaratarak bunları
tek tek birer öğe (CoolMenuItem) olarak Carousel kontrolümüze
ekliyoruz. Her bir CoolMenuItem'ın Content özelliğine herhangi
bir Silverlight nesnesi atayabilirsiniz. Bu ister bizim örneğimizdeki gibi bir
resim ister bir video, yani MediaElement olabilir.
Örnek Carousel Kontrolü (Tıklamayı unutmayın :))
Hepinize kolay gelsin...
Yeni yılda hayatınızı kolaylaştırma yolunda iddialıyım :) Bu sefer de benim
işimi çok kolaylaştıran bir aracı sizlerle paylaşacağım.
Visual Studio içerisinde F5'e bastığımızda System Tray'de beliren "ASP.NET Development Server"'ı hatırlarsınız. Aslında adı "Cassini" olan bu server
işimizi epeyce kolaylaştırır ve bizim her sererinde IIS'te sitemizi veya
uygulamamızı ayarlamamızı gerektirmeden uygulamanın sanal bir sunucu ortamında
test edilmesini sağlar.
Peki hiç herhangi bir projenizi doğrudan çalıştırıp görmek istediğinizde
mecburen Visual Studio ile açıp F5'e bastığınız oldu mu? :) Veya mecburen IIS'te
web site ayarlamak zorunda kaldınız mı? sadece sitenizi çalıştırabilmek için?
İşte bu işkence aslında sürekli yaşadığımız bir süreç ve çok kolay bir çözümü
var. Biz de Visual Studio gibi gidip Cassini'yi kullanabiliriz.
Aslında Cassini bizim bilgisayarlarımızda WebDev.WebServer.exe
olarak yüklü bulunuyor. Tabi ki EXE'yi doğrudan alıp taşıyamazsınız, çok sayıda
bağlantılı DLL vs de söz konusu. Ama biz bu EXE'ye doğru parametreleri
gönderirsek aynı Visual Studio'nun kullandığı gibi herhangi bir klasördeki
dosyaları web sunucudaymış gibi çalıştırabiliyor. Bu EXE'nin nasıl
kullanıldığını merak edenleri veya birazdan sizlerle tanıştıracağım uygulamanın
nasıl yazıldığını merak edenleri İngilizce blogumdaki
bir yazıya davet edebilirim :)
 Sağ tıkla sunucudaaymış gibi çalıştır!
Gelelim sadede... Infragistics'te çalışan J. Ambrose Little tüm bunları yaparak uygulamayı da bir SETUP paketi şeklinde hazırlamış ve bununla da kalmamış ve bu sistemi işletim sisteminin context menü'süne bağlamış. Yani özetle; herhangi bir klasöre sağ tıklayıp "ASP.NET 2.0 Web Server Here" dediğizde Cassini açılıyor ve söz konusu klasör içerisindeki uygulama server üzerinden çalıştırılıyormuş gibi karşınıza çıkıyor. Aynı Visual Studio'da F5'e basmış gibi :)
Uygulamayı aşağıdaki linkten bilgisayarınıza indirip yükleyebilirsiniz.
Cassini Web Server Launcher - 02012009_1.msi (355 KB)
ASP.NET 2.0 dediğine bakmayın 3.5 SP1 ile herhangi bir sorunu yok.
Hepinize kolay gelsin...
Yılın ilk yazısında yıl boyunca tüm yazılarınızda kullanabileceğiniz bir
kolaylıktan bahsetmek istiyorum; kod renklendirmek! Özellikle teknik makale
yazanların en büyük dertlerinden biri de Visual Studio içerisinde kod
renklendirmeleri gibi web sayfalarında da kodların renkli olarak gözükmesini
sağlamaktır. Bu kapsamda bazıları kodların resim dosyaları olarak sitelerine
koyar fakat bu durum okunabilirlilik açısından sorun yaratmasa da "kodları
kopyalayamayan milyonlar" :) tarafından küfür yemenize ramak kaldı demektir!
Bugün aslında çok basit bir JavaScript kütüphanesinden bahsedeceğiz. Bu
kütüphane sayesinde aşağıdaki dillerle yazılmış tüm kodları otomatik olarak
sayfa içerisinden JavaScript ile renklendirebiliyorsunuz.
|
Dil Adı |
Dile ait MicroFormat |
|
C++ |
cpp, c, c++ |
|
C# |
c#, c-sharp, csharp |
|
CSS |
css |
|
Delphi |
delphi, pascal |
|
Java |
java |
|
Java Script |
js, jscript, javascript |
|
PHP |
php |
|
Python |
py, python |
|
Ruby |
rb, ruby, rails, ror |
|
Sql |
sql |
|
VB |
vb, vb.net |
|
XML/HTML |
xml, html, xhtml, xslt |
Yukarıdaki listede desteklenen dillerin yanında bir de MicroFormat
tanımlarını bulabilirsiniz. Bunların ne şekilde kullanıldığına birazdan
değineceğiz.
Color Coding için altyapı hazırlıkları...
İlk olarak sitenizdeki tüm kodları PRE tagları arasına almanız gerekiyor.
Eğer kodlarınız içerisinde XML'de olduğu gibi < ve > işaretleri varsa bu sefer
de bir textarea kullanabilirsiniz. Söz konusu tagların hepsine isim olarak aynı
ismi vermeniz gerek. Ayrıca tagların CSS class isminin de yukarıdaki listede
bulunan dillere göre MicroFormat'lardan alınması şart. Gelin hızlı bir örnekle
nasıl bir şeyden bahsettiğimizi görelim.
<pre name="code" class="vb.net">
Dim x as string
</pre>
Gördüğünüz gibi PRE tagının ismi CODE ve
class değeri de vb.net şeklinde ayarlanmış. Birazdan
yazacağımız JavaScript kodunda sayfada adı code olan tüm
tagların içeriğinin renklendirilmesini belirteceğiz ve renklendirme yapılırken
her bir code adındaki tagın class ismine bakılarak hangi dilde
kod yazıldığını anlaşılacak. Peki tüm bunları nasıl yapacağız?
İlk olarak
buradan
kullanacağımız tüm JavaScript dosyalarını indirebilirsiniz. Dosyalar içerisinde
kodların görselliğini ayarlayacak bir CSS ve bir de clipboard kopyalama sistemi
için Flash dosyası bulunuyor. Özellikle bilgisayarınıza tüm dosyaları
indirdiğinizde scripts klasörüne bakarsanız aslında her dil için ayrı ayrı
JavaScript dosyaları bulunduğunu görebilirsiniz. Paketteki shCore.js
dosyası tüm renklendirme sisteminin ana dosyası. Diğer JS dosyaları ise ayrı
ayrı dillere özel olarak hazırlanmış. Bu dosyalardan hangilerini istiyorsanız
onları sayfanıza eklemeniz yeterli olacaktır.
<link type="text/css" rel="stylesheet" href="styles/SyntaxHighlighter.css"></link>
<script language="javascript" src="scripts/shCore.js"></script>
<script language="javascript" src="scripts/shBrushVb.js"></script>
<script language="javascript">window.onload = function ()
{ dp.SyntaxHighlighter.ClipboardSwf = '/scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');}</script>
Yukarıda gördüğünüz kodları sayfanıza yerleştirirseniz aslında tüm gerekli
ayarları da tamamlamış oluyorsunuz. Böylece gerekli CSS sınıfları ve JavaScript
kütüphaneleri sayfaya eklenmiş oldu. Son olarak sayfa açıldığında da hem
ClipBoard için kullanacağımız Flash dosyasını hem de sayfada taranacak tagların
isimlerini aktarmış olduk.
 Renklendirilmiş kodumuz.
Yukarıda gördüğünüz son görsel şekil yazdığımız kodların sonucu ortaya
çıkıyor. JavaScript kütüphanesi PRE taglarından böyle bir görsellik yaratıyor.
Eğer isterseniz bu görsellik içerisinde bazı noktaları da PRE taglarına ek
parametreler ekleyerek tanımlayabilirsiniz.
<pre name="code" class="vb.net:nocontrols:firstline[10]">">
Dim x as string
</pre>
Yukarıdaki kod içerisinde class değerinde kullandığımız dili
tanımladıktan sonra üst üste iki nokta koyarak diğer parametrelerimizi de
yazabiliyoruz. Bu parametrelerden nocontrols parametresi görsel
arayüzde üstteki düğmelerin gözükmemesini sağlarken firstline
ise kod görünümüzdeki ilk satırın satır numarasını belirliyor.
Hepinize yeni yılda bol paylaşımlı günler dilerim ;)
|
Copyright © 2010 Daron Yöndem.
Tüm hakları saklıdır.
|
|