Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!       
Daron Yöndem - September, 2009
bir yazılımcının tasarıları...
 Friday, September 25, 2009

Bu MUHTEŞEM! :) Beni çok heyecanlandıran ve sevindiren bir haberim var bugün sizlere. Dün Twitter üzerinden spoiler verdiğim WebsiteSpark programı Türkiye'de de duyuruldu! 10 kişiye kadar çalışanı olan ve ASP.NET, Silverlight, Sharepoint, PHP gibi teknolojilerle web uygulamaları geliştiren şirketlere 3 yıl süre ile ücretsiz .... bir sürü şey sağlanıyor :) Gelin sayalım isterseniz;

  • 3 adet Visual Studio 2008 Professional Edition Lisansı
  • 1 adet Expression Studio 3 lisansı (Expression Blend, Sketchflow ve Web!)
  • Ayrıca 2 adet Expression Web 3 lisansı.
  • Windows Web Server 2008 R2 4 işlemci lisansı
  • SQL Server 2008 Web Edition 4 işlemci lisansı
  • DotNetPanel yönetim paneli

Daha da güzeli var! SQL ve Windows Server lisanslarını isterseniz yayın ortamında da kullanabiliyorsunuz. Yani lisansnlar sadece geliştirme ortamı için değil bir hosting sağlayıcıdan alacağınız dedicated sunucunuza bu lisansları kurup uygulamanızı canlı yayına da alabilirsiniz. Tüm bunların yanında Microsoft Partner'ları gibi;

  • Firma başına iki teknik destek hakkı.
  • Microsoft’un web şirketleri ekosistemindeki iş ortakları, müşterileri ve tamamlayıcı servisleri ve teknolojilerinden oluşan topluluğa erişim hakkı.    
  • MSDN üzerindeki teknik bilgi ve danışmanlık sunan tartışma gruplarına sınırsız erişim.

hizmetlerinden de WebsiteSpark üyesi kuruluşlar faydalanabiliyor.

Başvuru için hemen http://www.microsoft.com/web/websitespark/ adresini ziyaret edebilirsiniz.

3 yıl sonra ne olacak?

Üç yılın sonunda eğer programdan ayrılmak isterseniz 100$'lık bir ödeme yapmanız gerekiyor. Fakat tahmin etmiyorum ki kimse ayrılsın çünkü bu üç senede yayında bile kullanabileceğiniz ücretsiz lisanslar ile çoktan firmanızı kuvvetli bir şekilde ayağa kaldırmış olmanız mümkün. Bu durumda da normal yöntemlerle yıllık 999$ vererek tüm bu lisansların development ortamında kullanılabilecek olanlarını alabilirsiniz ve yayın tarafı için de yine yıllık 199$ ile 1 adet Windows Web Server ve 1 adet SQL Server Web edition edinebilirsiniz. Kişisel kanaatimi sorarsanız bu rakamlar bile bir yazılım şirketinin masrafları arasında en ufak kalemleri oluşturacaktır.

Spark programları süper!

Microsoft bundan önce de öğrencilere ücretsiz lisans sağlayan DreamSpark ve yazılım üretimi yapan şirketlere ücretsiz lisans sağlayan BizSpark ile güzel bir seriyi başlatmıştı. Bu serinin WebsiteSpark ile devam etmesi gerçekten muhteşem. Artık bir yazılım şirketi kurmak veya bu ekonomik krizde şirketi tekrar ayağa kaldırmak, lisans dertleriyle uğraşmamak çok daha rahat.

"Helal olsun Microsoft" diyerek yazımı sonlandırıyorum ;)

Friday, September 25, 2009 11:51:40 AM (GTB Standard Time, UTC+02:00)  #    Comments [6]    | 
 Thursday, September 24, 2009

Bundan bir süre önce 1.0 sürümü ile karşımıza çıkan Web Platform Installer ilk gördüğümde antipati ile karşıladığım bir paketti. Aslına bakarsanız hala da öyle bakıyorum :) Tabi bunun nedenleri var fakat nedenlere bakmadan önce isterseniz gelin bir WPI nedir ona bakalım.

Şu an 2.0 sürümüne gelen WPI'ın amacı te bir yükleme ise bir bilgisayarda Web Platformu oluşturmak. Peki bunu nasıl yapabilir? 78KB'lık ufak bir Setup paketini bilgisayarınıza indirdikten sonra yükleme boyunca bilgisayarınıza yüklemek istedikleriniz soruluyor ve sonrasında sadece gerekli paketler indiriliyor. Aslında buı noktada WPI içerisinde ne gibi yüklemelerin olduğu çok önemli.

  • Web Server
  • .NET Framework 3.5 SP1
  • ASP.NET
  • SQL Server 2008 Express
  • SQL Server Driver for PHP
  • PHP 5.2.11
  • Silverlight Tools
  • Visual Web Developer 2008 Express
  • ASP.NET MVC
  • WebDav
  • Web Deployment

Nasıl? İşte tüm bu yüklemelerin bir paket olarak seçmeli bir şekilde yüklenebildiği bir yer WPI. Gördüğünüz gibi WPI'ın amacı ister PHP ister ASP.NET tarafında olun sizin için bilgisayarınıza gerekli platformu kurmak. Bugün bu yüklemelerin belki de çoğunu ayrı ayrı sitelerde bularak yapıyorsunuz. Oysa hep tek bir merkezden indirilebilir durumda. İşte benim antipati duyduğum şey de bu "otomatize" etme kısmı. "Control Freak" de diyebilirsiniz bana :) kendim elle tek tek yüklemedikçe rahat edemiyorum :) Ama bu dediğim gibi sadece bana özel bir "kıl dönmesi" durumu.

Web Platform Installer içerisindeki paketlerden birkaçı.
Web Platform Installer içerisindeki paketlerden birkaçı.

Gel vatandaş gel!

Peki yazılım geliştiriciler için platform sağlandı da ya sade vatandaş için? WPI içerisinde bir de "Wep Applications" kısmı var. Yani belki de yüklemek istediğiniz şey sadece WordPress'tir? Drupal, BlogEngine, SubText hepsi bu pakette var! Sadece bloglar değil, Umbraco gibi CMS'ler de var. Bu paketlerden herhangi birini seçtiğinizde gerekli olan platform yüklemeleri ile beraber bilgisayarınıza veya sunucunuza yüklenebiliyorlar!

Yükleme için http://www.microsoft.com/web/ adresini ziyaret edebilirsiniz.

Hepinize kolay gelsin.

Thursday, September 24, 2009 12:15:46 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]    | 
 Friday, September 18, 2009

Visual Studio 2010 ile beraber gelecek olan Web.Config Transformasyonu projelerinizi Staging, Production gibi ortamlara daha rahat deploy etmenizi sağlayacaktır. Zekice bir özellik!

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Friday, September 18, 2009 11:31:53 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   ASP.NET 4.0 | Visual Studio 2010  | 
 Thursday, September 17, 2009

.NET Framework 4.0 ile beraber gelecek güzel özelliklerden biri de artık dahili hale gelen Parallel Programlama özellikleri. Thread management yerine Task Managemenet, Parallel shared functionlar ve en güzeli PLINQ ile ilgili neler geliyor merak ediyorsanız hemen videoyu izlemenizi tavsiye ederim :)

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Thursday, September 17, 2009 11:29:56 AM (GTB Standard Time, UTC+02:00)  #    Comments [2]   Visual Studio 2010 | PLINQ  | 
 Wednesday, September 16, 2009

Visual Studio 2010 ile beraber Visual Basic 2010 da geliyor. Bu görsel derste Visual Basic 2010'a bir ön gezi düzenliyoruz. Dile dair yeni gelen özellikleri merak ediyorsunuz kaçırmayın derim.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Wednesday, September 16, 2009 11:27:11 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Visual Basic 2010 | Visual Studio 2010  | 
 Tuesday, September 15, 2009

URLReWrite, URLMapping veya URLRouting adını ne koyarsanız koyun bugün web projelerinin olmazsa olmazlarından biri de web siteleri içi linklerin okunabilir ve arama motorları tarafından rahatlıkla anlaşılabilir hale getirilmesi. Bunun için kullanılabilecek kolay veya zor birçok teknik var. Bunlardan bazıları request başına gelen adresi alıp değerlendirirken bazıları daha alt seviyelerden de ilerleyebiliyor. Bu noktada bence önemli olan olabildiğince dış ürün veya kütüphanelere başvurmadan ASP.NET içinde çözümü üretiyor olmak.

Aslında URLRouting şu anda ASP.NET MVC'de ve DynamicData projelerinde zaten kullanılıyor. Birkaç takla atarak aynı kütüphaneleri normal ASP.NET projelerine almak da mümkün. ASP.NET 4.0 tarafında ise çok daha rahat kullanıma sahip bir şekilde URLRouting karşımıza çıkıyor.

İlk olarak gelin Routing kurallarımızı belirleyelim. Bunun için sitemize bir Global.asax dosyası ekleyerek Application'ın Start event'ında gerekli tanımlamaları yapabiliyoruz.

[VB]

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)

    Routing.RouteTable.Routes.Add("Sayfalar",

                                new Routing.Route("sayfa/{adi}",

                                new Web.Routing.PageRouteHandler("~/sayfa.aspx")))

End Sub

Yukarıda gördüğünüz kod içerisinde sanal yol olarak tanımladığımız sayfa/Daron şeklindeki adresleri sayfa.aspx'e yönlendiriyoruz. Peki "daron" parametresine ne oldu dediğinizi duyar gibiyim. Dikkat ettiyseniz aslında Daron parametresini adi adında bir değişkene aktarmış olduk. Bu değişken otomatik olarak sayfa.aspx'e gönderilecek. Sayfa.aspx içerisinde bu gibi parametrelere ulaşmak için de aşağıdaki kodu kullanabiliyoruz.

[VB]

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    Dim Gelen As String = Page.RouteData.Values("adi")

    Response.Write(Gelen)

End Sub

İşte bu kadar basit. Ne kadar kolay değil mi? İsterseniz Application Startup durumda çok sayıda Routing tanımlayabilirsiniz. Tüm bu Routingler içerisindeki değerler uygun sayfalara parametre olarak gönderilecektir. Söz konusu sayfalar da bu parametreleri alarak gerekli işlemleri yapabilirler.

RouteUrl ve RouteValue

Peki ya belirli bir sayfadan diğerine link vereceksek? Hatta link verilen sayfada da parametreyi sayfa içerisindeki HTML kodunda kullanacaksak? Bir üstteki örnekte basit bir şekilde "Daron" parametresini sayfa Routing'ine gönderdik ve sayfa.aspx de bunu alıp ekrana yazdı. Oysa bunu yapmanın çok daha kolay bir yolu daha var.

Kısa yolda URLRouting'e özel link.
Kısa yolda URLRouting'e özel link.

Gördüğünüz gibi expression builderlar kullanarak hızlıca gerekli linki yaratabiliyoruz. İşin güzel tarafı eğer Global.asax içerisinde parametre olarak "adi" parametresini alan Routing kuralını değiştirirseniz bir anda tüm projenizdeki linklerin de uygun şekilde değişip güncel hallerinin yaratılıyor olması. Böylece hiç uğraşmadan dinamik bir altyapı yaratmış oluyorsunuz.

[ASP.NET]

<form id="form1" runat="server">

    <asp:Label ID="Label1" runat="server" Text="<%$RouteValue:adi%>" />

</form>

Ayrıca yukarıdaki şekilde herhangi bir sayfaya gelen parametreyi de RouteValue expression ile rahatlıkla alıp sayfada kullanabilirsiniz.

Hepinize kolay gelsin.

Tuesday, September 15, 2009 12:23:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [13]   ASP.NET 4.0  | 
 Monday, September 14, 2009

ASP.NET'teki performans optimizasyonu açısından en sevmediğimiz fakat yine işimizi kolaylaştırdığı için kullanmak durumunda kaldığımız bir diğer özellik de ViewState. Sayfa içerisinde kontrollerin State/Durum'larını saklayabilmesini ve PostBack sonrasında aynı durum ile devam edebilmesini sağlayan bu altyapı neden sevilmez?

ViewState canavarı!
ViewState canavarı!

İşte tam da yukarıdaki manzara nedeniyle ViewState'i sevmeyiz oysa ViewState candır :) Çünkü işimizi çok kolaylaştırır. Önemli olan tam olarak nerede ViewState'i kullanacağımıza karar vermemizdir. Örneğin bir web sayfasında hiç postback yoksa neden ViewState kullanalım? Eğer söz konusu sayfadan sürekli başka sayfalara yönlendirmeler yapıyorsanız ne gerek var? Veya daha da farklısı, sayfanın kendi state'ini saklamasına gerek yoksa neden kullanalım? Varsayılan ayarları ile her yerde açık gelen bu ViewState canavarını eğer kontrol ederseniz aslında çok da faydanıza çalışabilir bir araç haline gelebilir.

Bugüne kadar ViewState'i sayfa bazında veya kontrol bazında pasif hale getirebiliyorduk. Bunun için basit bir şekilde kontrolümüzün EnableViewState özelliğini değiştirmemiz yeterli oluyordu.

[ASP.NET]

 <asp:GridView EnableViewState="true" ID="BirGrid" runat="server">

</asp:GridView>

Ama ufak bir sorun var. Ya ben tüm sayfada ViewState'i kapatmak fakat özellikle bir kontrol için açmak istiyorsam? Maalesef bunu yapamıyoruz. Peki o zaman bu makalenin amacı ne? ASP.NET 4.0 ile beraber artık kontrol başına birbirinden bağımsız olarak ViewState'in kullanılıp kullanılmayacağını ayarlayabiliyorsunuz.

ViewStateMode karşınızda.
ViewStateMode karşınızda.

Artık tüm sayfada ViewState'i kapatsanız da kontrol başına ViewStateMode ayarlayarak ilerleyebilirsiniz. Söz konusu ayara ait seçenekler zaten çok basit. Enabled / Disable ViewState'i o kontrol için açıp kapatırken Inherit ise bir üst kontrolün özelliğinin alt kontrolde de geçerli olmasını sağlıyor.

Hepinize kolay gelsin.

Monday, September 14, 2009 12:21:25 PM (GTB Standard Time, UTC+02:00)  #    Comments [7]   ASP.NET 4.0  | 
 Sunday, September 13, 2009

ASP.NET'te en sevmediğim özelliklerden biri yaratılan HTML kodu üzerindeki kontrolün pek de mümkün olmaması. Aslında bu sevmediğim özellik ASP.NET'in işimizi bu kadar kolaylaştırabilmesini sağlayan en önemli altyapısı ile ilişkili. Fakat derdime çare arayacak olsam aslında tam olarak da yaratılan HTML kontrollerinin ID'lerine takıldığımı söyleyebilirim. Boyumu aşan ID'leri kontrol edememek bir de bu ID'lere JavaScript ile ulaşmak zorunda kalmak ölümcül bir deneyim!

Neden bahsediyorsun?

Bahsettiğim şey aslında basit bir Repeater bile olabilir. Örneğin sayfanıza bir Repeater yerleştirdiniz ve içinde de çok basit bir Label bulunuyor. Aslında tek yapmak istediğiniz elinizdeki ürünlerin isimlerini listelemek diyelim. Bu durumda kabaca kullanacağınız Repeater yapısı aşağıdaki gibi olacaktır.

[ASP.NET]

<asp:repeater id="Repeater1" runat="server">

    <ItemTemplate>

        <asp:Label ID="lbl_UrunAdi" runat="server" Text='<%# Eval("Adi") %>'></asp:Label>

    </ItemTemplate>

</asp:repeater>

Peki bu ASP.NET kodu çalıştığında ortaya HTML olarak ne çıkacak dersiniz? Gelin aşağıdaki HTML'i beraber inceleyelim.

 [HTML]

<span id="Repeater1_ctl00_lbl_UrunAdi">Örnek1</span>

<span id="Repeater1_ctl01_lbl_UrunAdi">Örnek2</span>

<span id="Repeater1_ctl02_lbl_UrunAdi">Örnek3</span>

<span id="Repeater1_ctl03_lbl_UrunAdi">Örnek4</span>

<span id="Repeater1_ctl04_lbl_UrunAdi">Örnek5</span>

<span id="Repeater1_ctl05_lbl_UrunAdi">Örnek6</span>

<span id="Repeater1_ctl06_lbl_UrunAdi">Örnek7</span>

<span id="Repeater1_ctl07_lbl_UrunAdi">Örnek8</span>

<span id="Repeater1_ctl08_lbl_UrunAdi">Örnek9</span>

<span id="Repeater1_ctl09_lbl_UrunAdi">Örnek10</span>

Yukarıdaki kodda da gördüğünüz üzere her bir Label / Span tagının ayrı bir ID'si var. Zaten olması gereken de bu, çünkü bir sayfada ancak aynı ID'den bir adet bulunabilir. Fakat ASP.NET'in bu farklı ID'leri yaratırken izlediği yol biraz farklı. İlk olarak container elementin adı alınıyor sonra ctl ile başlayan satır Index numarası kullanılıyor sonra da içerideki orijinal kontrolün adı ekleniyor ve ortaya kocaman bir ID çıkıyor. Bu ID'lerin her birini üç karakterlik isimlere kısaltmış olsak ciddi miktarda web sitesi trafiğini de azaltmış olacağız. Hadi trafiği geçtik bu Label'lardan birine JavaScript ile ulaşmak isterseniz ne yapacaksınız? Eminim çoğunuzun dinamik JavaScript kodları yarattığı ve içlerine sunucu tarafından istedikleri kontrollerin ClientID'lerini koydukları günler vardı. Geçmiş zamanla konuşuyorum çünkü ASP.NET 4.0 ile bu sistem değişiyor.

Hoş geldin ClientIDMode!
Hoş geldin ClientIDMode!

Artık kontrol başına ClientIDMode belirleyerek söz konusu kontrolün istemci taraflı ID'sinin ne şekilde yaratılacağını kontrol edebiliyoruz. Peki ClientIDMode için gelen seçenekler nelerdir?

AutoID: Herşey eskisi gibi devam eder.
Inherit: Bir üst kontrolde bu özellik nasıl ayarlanmış ise aynısı alt kontrolde de geçerli olur.
Predictable: Eski ID'lere benzeye fakat şekli şemali kontrol edilebilir ID yapıları oluşturulmasını sağlar. Bu yapı daha fazla DataBound kontrollerin içi için kullanılır.
Static: Söz konusu kontrolün sunucu tarafındaki ID'si ne ise istemci tarafındaki da bire bir aynı olur. Bu noktada bir sayfa içerisinde aynı ID'nin tekrar kullanılmaması sizin sorumluluğunuzdadır. Özellikle Repeater gibi yapıların içinde kullanımı tehlikeli olabilir.

Static

Eğer herhangi bir kontrolün ClientIDMode'unu Static olarak ayarlarsanız sunucu tarafındaki ID doğrudan istemciye gönderilecektir. Örneğin bir üstteki Repeater içerisindeki Label'ın ClientIDMode özelliğini Static yaparsak alacağımız sonuç aşağıdaki gibi olur.

[HTML]

 <span id="lbl_UrunAdi">Örnek1</span>

<span id="lbl_UrunAdi">Örnek2</span>

<span id="lbl_UrunAdi">Örnek3</span>

<span id="lbl_UrunAdi">Örnek4</span>

<span id="lbl_UrunAdi">Örnek5</span>

<span id="lbl_UrunAdi">Örnek6</span>

<span id="lbl_UrunAdi">Örnek7</span>

<span id="lbl_UrunAdi">Örnek8</span>

<span id="lbl_UrunAdi">Örnek9</span>

<span id="lbl_UrunAdi">Örnek10</span>

Gördüğünüz gibi tüm Span tagları aynı ID özelliğine sahip. Bu durum tabi ki tehlikeli çünkü bu durumda bir JavaScript ile bu kontrollerin hiçbirini bulamayız. Zaten durum kurallara aykırı fakat yaptığımız hata basit. Static modu kesinlikle DataBound kontrollerin içerisindeki kontrollerde kullanılmamalı. DataBound kontroller hariç sayfada tekil kullandığınız kontroller için rahatlıkla Static modunu kullanabilirsiniz.

Predictable

Databound kontrollerin içi için kullanılabilecek en anlamlı çözüm Predictable modudur. Bu modda varsayılan ayarları ile ilk önce container elementin ismi alınır sonra iç elementin ismi alınır ve en sona da Index numarası yerleştirilir. Yine en üstteki Repeater örneğimizi ele alalım ve Repeater'ın ClientIDMode özelliğini aşağıdaki gibi Predictable şeklinde düzenleyelim.

[ASP.NET]

<asp:Repeater ID="Repeater1" runat="server" ClientIDMode="Predictable">

    <ItemTemplate>

        <asp:Label ID="lbl_UrunAdi" runat="server" Text='<%# Eval("Adi") %>'></asp:Label>

    </ItemTemplate>

</asp:Repeater>

Kodumuzu çalıştırdığımız aldığımız HTML sonucu aşağıdaki şekilde olacaktır.

 <span id="Repeater1_lbl_UrunAdi_0">Örnek1</span>

<span id="Repeater1_lbl_UrunAdi_1">Örnek2</span>

<span id="Repeater1_lbl_UrunAdi_2">Örnek3</span>

<span id="Repeater1_lbl_UrunAdi_3">Örnek4</span>

Gördüğünüz gibi en azından bildiğim isimler kullanılmış ve ana repeater'in isminin yanına label'ın ismi sonra da Index numarası yerleştirilmiş. Bu noktada maalesef Repeater ve Label'a verdiğimiz isimlerin uzunlukları da önem kazanıyor.

Predictable modunda kullanabileceğiniz bir diğer özellik ise ClientIDRowSuffix özelliği. Fakat maalesef bu özelliği sadece DataKey koleysiyonları tutan kontrollerde kullanabilirsiniz. Örneğin bir GridView bunun için uygun olacaktır.

[ASP.NET]

<asp:gridview id="BirGrid" runat="server" autogeneratecolumns="false" clientidmode="Predictable"

    clientidrowsuffix="ID">

    <Columns>

        <asp:TemplateField HeaderText="ID">

            <ItemTemplate>

                <asp:Label ID="lbl_Adi" runat="server" Text='<%# Eval("Adi") %>' />

            </ItemTemplate>

        </asp:TemplateField>

    </Columns>

</asp:gridview>

Yukarıda gördüğünüz GridView'ın ClientIDRowSuffix özelliğine ID değeri verilmiş. Böylece yaratılan ID'lerin sonunda artık Index numarası değil doğrudan veritabanından gelen ID değeri yerleştirilecek.

[HTML]

<table cellspacing="0" rules="all" border="1" id="BirGrid" style="border-collapse: collapse;">

    <tr>

        <th scope="col">

            ID

        </th>

    </tr>

    <tr>

        <td>

            <span id="BirGrid_lbl_Adi_3">Örnek1</span>

        </td>

    </tr>

    <tr>

        <td>

            <span id="BirGrid_lbl_Adi_4">Örnek2</span>

        </td>

    </tr>

    <tr>

        <td>

            <span id="BirGrid_lbl_Adi_5">Örnek3</span>

        </td>

    </tr>

    <tr>

        <td>

            <span id="BirGrid_lbl_Adi_6">Örnek4</span>

        </td>

    </tr>

Hemen kodumuzdaki Label'ların ID'lerine bakarsak Grid'in adını, sonra Label'ın adını ve en sonunda da ID değerlerini görebiliyoruz. Malum ID değerlerin kayıtların sırası ile aynı olmayabilirler. Bu gibi bir teknik ile kontrollerin ID'leri set edildiğinde JavaScript ile veritabanından gelen değerlere göre sayfada uygun kontrolleri bulmak da çok daha kolaylaşıyor.

Başka nasıl ayarlanır?

Eğer isterseniz ClientIDMode özelliğini projelerinde sayfa bazında veya uygulama bazında da ayarlayabilirsiniz.

<%@ Page Language="VB" AutoEventWireup="false" ClientIDMode="Static" CodeFile="Default.aspx.vb" Inherits="_Default" %>

Yukarıdaki şekli ile bir sayfada ClientIDMode ayarlamak tüm sayfa için geçerli olmasını sağlayacaktır. Ayrıca uygulama bazında da Web.Config içerisinde gerekli ayarı yapabilirsiniz.

<system.web>

    <pages clientIdMode="Predictable"></pages>

</system.web>

Hepinize kolay gelsin.

Sunday, September 13, 2009 12:19:39 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   ASP.NET 4.0  | 

DeepZoom Composer gün geçtikçe daha da gelişiyor ve bir yazılımcı / tasarımcı aracı olmaktan çıkıp artık son kullanıcıların da kullanabileceği bir araç halini alıyor. Bu görsel derste DeepZoom Composer'ın son haline göz atıyor ve yenilikleri inceliyoruz. Umarım faydalı olur.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Saturday, September 12, 2009 11:29:23 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Görsel Ders | Silverlight 3.0  | 
 Saturday, September 12, 2009

Dokuz aylık mail grubumuzun ikinci İstanbul buluşmasını bir iftarda toplanarak yaptık. Benim için her zamanki gibi çok zevkli bir buluşma oldu. Umarım katılan herkes iyi vakit geçirmiştir.

Mail grup 2. İstanbul buluşması.
Mail grup 2. İstanbul buluşması.

Bu sefer konuştuğumuz konulardan bahsetmeyeceğim :) Mail grup buluşmalarında konuşulanlar orada kalır :) Merak edenler bir dahakine gelir. Bu arada mail gruba katılmak isteyenlere de her zaman kapımız açık ve dönen mail miktarı nedeniyle sonra şikayetçi olmayın :)

Buluşmadaki tüm fotoğraflara buradan ulaşabilirsiniz. Fotoğraflar için her zamanki gibi Tuba'a teşekkür ediyorum.

Saturday, September 12, 2009 12:11:53 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]    | 

Geçenlerde çok güzel bir şekilde tasarlanmış bir Silverlight uygulamasında eski klasik tarz bir MessageBox gördüm ve hemen "Aman tanrım!" tepkisini vermekten kendimi alamadım. Oysa aslında ne kadar da kolay özel bir MessageBox yaratıp projelerimizde kullanmak. Bu videomuzda Silverlight içerisinde ChildWindow kontrolünü alarak bir MessageBox'a çeviriyoruz. Umarım faydalı olur.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Friday, September 11, 2009 11:27:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [6]   Expression Blend | Görsel Ders | Silverlight 3.0  | 
 Friday, September 11, 2009

Bir süre önce aldığım bir mail beni biraz şaşırtmıştı. Aldığım mailde Silverlight ile basit bir SlideShow uygulamasının nasıl yapılabileceği soruluyordu. Şaşırmammın nedeni ise aslında bu gibi bir uygulamanın yapılabilmesi için herşeyi blogda anlatmış olduğumu düşünmemdi. Oysa baktım ki ufak bir nokta eksik ve bunun üzerine aşağıdaki videoyu çekmeye başladım. Videomuzda Silverlight ile basit bir SlideShow uygulaması geliştiriyoruz. Umarım faydalı olur.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Thursday, September 10, 2009 11:23:54 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Görsel Ders | Silverlight 3.0  | 
 Wednesday, September 09, 2009

Visual Studio 2010 Beta çıkalı epey oluyor. Performans açısından şu an için bir beklenti çok yanlış olsa da gelen yeni bazı özelliklerden erkenden haberdar olmanın da zararı olmaz sanırım. Sizin için hazırladığım aşağıdaki video ile siz de hızlıca yeni gelen özelliklerin bir kısmına göz atabilirsiniz.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Wednesday, September 09, 2009 10:57:22 AM (GTB Standard Time, UTC+02:00)  #    Comments [1]   Visual Studio 2010  | 

Tasarımcılar ile yazılımcılar arasındaki iletişim sorunları çözmek projelerin işleyişindeki en önemli noktalardan biri. Expression Blend 3 ve Visual Studio'nun kullanımı ile bir tasarımcı ile yazılımcının sorunsuz olarak beraber çalışmaları mümkün. Sizler için hazırladığım bu videoda Expression Blend 3'ün data bağlama özelliklerini inceliyoruz.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Tuesday, September 08, 2009 11:20:43 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Expression Blend | Görsel Ders | Silverlight 3.0 | WPF  | 
 Tuesday, September 08, 2009

Expression Blend 3 ile beraber gelen ilginç özelliklerden biri de SketchFlow. Sketchflow hakkında sizler için hazırladığım bu videoyu umarım beğenirsiniz.

Yukarıdaki videoyu bilgisayarına indirmek isteyenler nedirtv.com'u ziyaret edebilirler.

İyi seyirler...

Monday, September 07, 2009 11:18:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Expression Blend | Silverlight 3.0 | WPF  | 
 Sunday, September 06, 2009

Neredeyse her tür yazılım projesinde prototip geliştirmek çoğu zaman başvurduğumuz bir süreç oluyor. Bazen bu prototipleri sadece yapacağımız projenin fizibilitesini ölçmek amacı ile geliştirsek de bazen de amacımız müşterimize gelecekte elde edeceği ürünü kabaca göstermek de olabiliyor. İşin en sıkıcı tarafı ise çoğu zaman bu prototiplerin teklif aşamasında kullanılması nedeniyle aslında kuyuya atılan bir taştan farklı olmamaları. Yani prototipiniz karşılığında eğer hedef projeyi teklifiniz ile alamazsanız hiçbir ücret alamayabilirsiniz. Sektörde karşılaşabileceğiniz farklı senaryolara değinmek yerine işin biraz daha teknik kısmına geçip bu süreçlerde işimizi kolaylaştırmak adına neler yapabiliriz ve bu çerçevede Expression Blend bize nasıl yardımcı olabilir sorularına cevap vereceğiz.

Sketchflow

Expression Blend 3 ile beraber SketchFlow denilen bir mekanizma, proje şablonu geliyor. Sketchflow'un amacı prototip geliştirmeyi kolaylaştırmak ve olabildiğince bu süreçlerde müşteri ile interaktif bir sistem sağlamak. Sketchflow projelerini hem WPF hem de Silverlight tarafında kullanabilirsiniz. Her iki altyapıda da aynı şekilde çalışıyor. Hemen Expression Blend ile yeni bir Silverlight Sketchflow projesi yaratalım.

İlk Sketchflow projemizi yaratıyoruz.
İlk Sketchflow projemizi yaratıyoruz.

Normal bir Blend projesine göre Sketchflow projeleri Blend ile açıldığında ekranda iki farklı bölüm daha oluşacaktır. Bu bölümlerden birinin adı "Map" diğeri ise "Sketchflow Animation" şeklinde. Sketcthflow'un mantığında prototip geliştirmek olduğu için geliştireceğiniz prototip uygulamanın haritası tabi ki çok önemli. Uygulamada hangi sayfalar olacak? Hangi sayfadan hangi sayfaya geçişler yapılacak? gibi tüm soruları harita üzerinde gerekli kontrolleri yarattıkça cevaplamış oluyorsunuz.

SkethFlow projelerinde Map üzerinde çalışmak.

Skethflow ile bir prototip geliştirirken tüm projenizin bir haritasını yarattığınızı düşünebilirsiniz. Her ekranınız için haritada bir sayfa yaratmanız gerekiyor. Sayfalara farklı isimler verebilirsiniz. Herhangi bir sayfanın fare ile üzerine geldiğinde yukarıdaki görselde görebileceğiniz gibi bir menü gözükecektir. Bu menüde en sağdaki düğmeye bastığınızda söz konusu sayfanın harita üzerindeki rengini değiştirebilirsiniz. Böylece harita çok daha anlamlı ve okunaklı olacaktır. Diğer yandan haritadaki sayfaları birbirlerine uygun şekilde bağlayarak haritadınızı tamamlamak da çok önemli. Bunu yapmak için ister sayfaları tek tek yaratıp sonra menülerindeki soldan ikinci düğmeyi kullanarak sayfaları birbirlerine bağlayın ister herhangi bir sayfanın altındaki menüden soldan ilk düğmeyi kullanarak söz konusu sayfaya bağlantılı yeni bir sayfa yaratın, seçim sizin. Son olarak her sayfanın menüsünde soldan üçüncü düğme ise birden çok sayfada kullanılabilecek Component'ler oluşturmanızı sağlayacaktır. Bu konuyu da ileride detaylıca inceleyeceğiz.

Harita üzerinde yaptığınız her işlem otomatik olarak projenize yansıyacaktır. Harita içerisinde oluşturduğunuz sayfalar aslında projenizdeki ayrı bir XAML olarak saklanacaktır. Bu XAML sayfalarını ayrı ayrı açıp her zamanki gibi Blend içerisinde tasarımınızı yapabilirsiniz.

Tasarım yaparkan kullandığınız stillere dikkat!

Unutmayın ki bir prototip tasarlıyoruz. Prototipte amacımız ürünü müşteriye beğendirmekten öte aslında ileride ne gibi bir ürünle karşılaşacağına dair fikir vermek. Eğer projenin tüm görsel tasarımını da yapmak zorunda kalırsak işimiz ciddi zorlaşabilir. Oysa dediğimiz gibi yapmak istediğimiz şey sadece "nasıl birşey olacak?" kısmını müşteriye göstermek ve görsel detaylara takılmalarını olabildiğince engellemek.

Bunun için Sketchflow projelerinde kullanabileceğiniz özel olarak stillerle değiştirilmiş kontroller bulunuyor. "Asset Library" altında "Styles" tabına göz atarsanız normal projelerde bulunmayan SketchStyles seçeneğini bulacaksınız.

Sketchflow'a özel SketchStyles.
Sketchflow'a özel SketchStyles.

Yukarıdaki ekran görüntüsünde de görebileceğiniz üzere SketchStyles kontrollerini kullandığımızda zaten kontrollerin tasarımları gereği müşterimize "bu bir konsept tasarımdır" mesajını vermiş oluyoruz. Kimse bu şekilde hazırlanmış bir ekran görüntüsünün tasarımını eleştirmeyecek ve herkes tasarımın konsept olarak geliştirildiğini anlayacaktır. Böylece bir dertten daha kurtularak prototipimizi geliştirmeye devam edebiliriz.

Navigasyon

Ekranlarınızı tek tek tasarladıkça ekranlar arası geçişlerin de nasıl yapılabileceği önem kazanacaktır. Bir prototip ürettiğimize göre kod ile sayfalar arası geçiş yapacak değiliz. Konunun çok daha basit bir çözümü olsa gerek. Herhangi bir kontrol üzerine ekranda sağ fare tuşu ile tıklarsanız karşınıza gelen menünün en altında Navigate komutunu bulabilirsiniz.

Navigasyonun kolay yolu.
Navigasyonun kolay yolu.

Gördüğünüz gibi içerisinde olduğumuz Giris sayfasında gidebileceğimiz tüm seçenekler Navigate To menüsünde bulunuyor. Şu an için uygulamamızın haritasında Giris sayfası ile Sonuc sayfası birbiri ile ilişkilendirimiş değil. Yine de Navigate To menüsünden eğer Sonuc sayfasını seçerseniz uygulama haritanız da bu bilgiye göre yenilenecek ve Giris ile Sonuc sayfaları birbiri ile ilişkilendirilecektir.

Not: SketchFlow projelerinde Blend Behavior'larını kullanabilirsiniz. Bu şekilde çok daha zengin işlevsellikteki prototipleri tek satır bile kod yazmadan yaratabilirsiniz.

Animasyonlar?

SketchFlow projelerinizde isterseniz StoryBoard'lar kullanabilirsiniz fakat genelde prototip üretirken çok kompleks animasyonlar yerine genel anlamda ekranla ilgili animasyonları üretmek daha mantıklı olacaktır. Örneğin ekrandaki bir menü gözüküp kaybolacak veya soldan alışveriş sepeti gelecek gibi bir animasyon çok daha anlamlı olabilir. Bu gibi durumlarda StoryBoard'lara kıyasla daha kolay kullanılabilen SketchFlow Animation'larından faydalanabilirsiniz.

SketchFlow animasyonlarını yaratmanın yolu.

SkethFlow animasyonlarında tüm ekranın aslında birer State serisi olarak kaydedildiğini düşünebilirsiniz. Ekranın farklı durumları vardır ve bunlar ayrı ayrı kareler olarak kaydedilerek bu kareler arası geçiş süreleri, ivmeleri vs belirlenir. Sonrasında bu animasyon herhangi bir kontrol tarafından hızlıca tetiklenebilir.

SkethFlow animasyonlarını oynatırken.
SkethFlow animasyonlarını oynatırken.

Herhangi bir kontrole sağ tıkladıktan sonra gelen menüde "Play SkethFlow Animation" seçeneğini göreceksiniz. Bu seçenek altında projenizde bulunan animasyonların bir listesi bulunacaktır. İstediğinizi seçerek söz konusu kontrol tarafından animasyonun tetiklenmesini sağlayabilirsiniz.

Prototipi yayınlayalım!

Prototipiniz tamamen hazır olduktan sonra büyük ihtimal ile çalışmanızı müşteriniz ile paylaşmak isteyeceksiniz. Bu gibi bir durumda yardımızda "SketchFlow Player" yetişecek. SketchFlow projelerinin ayrı kenilerine özel player yazılımları var. Bu yazılımlar WPF tarafında ve Silverlight tarafında tamamen aynı gibi gözükse de aslında WPF'te bir EXE olarak Silverlight'ta ise bir web sitesi olarak karşımıza çıkıyorlar. Projenizi bitirdikten sonra Blend içerisinde F5'e basmanız yeterli olacaktır.

SketchFlow Player karşınızda.
SketchFlow Player karşınızda.

Bahsettiğimiz üzere SketchFlow player duruma göre bir Silverlight veya WPF uygulaması olabiliyor. Player içerisinde prototipinizdeki tüm sayfalar gösterilir. Sol üst "Navigate" ekranın sürekli olarak içerisinde bulunan sayfadan hangi sayfalara geçiş yapılabileceği gösterilir. Sol altta ise uygulamanın haritası görülebilir. Tabi ana ekranda ise prototipiniz gösterilir ve herşey tıklanabilir, kullanılabilir durumdadır. İşin en güzel tarafı ise müşteriniz bu player üzerinden projeyi incelerken yorumlar da yapabilir.

Müşteriden gelen yorumlar.
Müşteriden gelen yorumlar.

SketchFlow Player içerisinde rahatlıkla müşteriniz "Feedback" ekranını kullanarak doğrudan proje üzerine yorumlarını ekleyebilir. Bu yorumlar sonrasında Export düğmesi ile bir XML'e alınıp Blend içerisinde de açılabiliyor. "Window" menüsünden "Feedback" kısmını ekrana getirdikten sonra müşterinizden gelen XML'i ekleyerek doğrudan projeniz üzerinde görebilirsiniz.

Müşteri yorumları Blend içerisinde.
Müşteri yorumları Blend içerisinde.

Müşterim ekran görüntülerini teklifin içinde istiyor!

Biliyorum, bazı müşteriler illa ekran görüntülerini ve prototipi kağıt üzerinde görmek ister. Dokümanlamak isterler. Konumuz müşterinin haklı veya haksız olduğu olmadığına göre biz bu işi nasıl çözeriz ona bakalım. Aslında pek bakacak birşey de yok, çünkü işimiz çok kolay. Prototipiniz bittikten sonra "File" menüsünden "Export to Microsoft Word" komutunu verebilirsiniz.

Projemizin detayları bir Word dokümanında.
Projemizin detayları bir Word dokümanında.

Projenizdeki her ekran ayrı birer sayfada ekran görüntüsü ile beraber Word'e aktarılacaktır. Dokümanın ilk sayfasında hem projenizin haritası hem de iç sayfalara dair linkler ve indeks de otomatik olarak hazırlanacaktır. Eh, gönül daha ne ister?

Expression Blend içerisinde SketchFlow hangi amaçla kullanırsanız kullanın müşterilerinizle ilişkinizi kolaylaştıracağı veya bir adım ileriye taşıyacağı kesin.

Hepinize kolay gelsin.

Sunday, September 06, 2009 9:44:39 AM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Expression Blend | Silverlight 3.0 | WPF  | 
 Saturday, September 05, 2009

Silverlight projelerinizde web servisleri kullandığınızda standart olarak "Add Service Reference" komutunu kullanıyoruz. Bu komut ile yaratılan service proxy doğal olarak sürekli yaratıldığı andaki hedefine göre çalışmayı amaçlıyor. Bu noktada da projenin yayına alınması noktasında service reference'ınızı yeni adres ile update etmek zorunda kalabiliyorsunuz.

Bir diğer sorun ise birden çok alan adının yönlendirildiği web sitelerinde olabiliyor. Varsayalım ki hem x.com hem de y.com aslında aynı siteyi açıyorlar ve sizin SL uygulamanıza da service reference x.com adresi üzerinden eklendi. Bu durumda SL uygulamanız x.com'da rahatlıkla çalışırken y.com'da çalışmayacaktır çünkü y.com'daki SL uygulamanız hala servis için x.com'a gitmeye çalışacaktır ve bu da cross-domain request kuralları gereği mümkün olmayacaktır.

Cross-domain'e izin verebiliriz dediğinizi duyar gibiyim fakat aslında gerek yok. Hem bu şekilde farklı alan adlarında yayınlanan sitemizi hem de makinemizdeki test alanı ile production'taki alanı tanıyabilen bir Silverlight uygulaması çok daha iyi olur.

[VB]

    WithEvents RSS As RSSService.rssSoapClient

Diyelim ki yukarıdaki şekilde tanımladığınız bir web servisiniz var. Normalde bu servisi service referecen eklenirkenki adrese hedefleyecektir. Oysa bu web servisini yaratırken kullandığımız constructor'lar arasında bir de parametre alan constructorlar var. İşte tam da o noktaya dokunmamız gerek.

[VB]

        Dim uri As New Uri(App.Current.Host.Source, "../RSS.asmx")

        Dim binding As New BasicHttpBinding(BasicHttpSecurityMode.None)

        binding.MaxReceivedMessageSize = 10000000

        Dim endpoint As New EndpointAddress(uri)

        RSS = New RSSService.rssSoapClient(binding, endpoint)

Yukarıda gördüğünüz kodda hem bir Binding hem de endpoint tanımlıyoruz. Böylece yarattığımız servis hangi binding tipini ve hangi endpointi kullanacağını bizden parametre olarak alacak. Özellikle endpoint demek zaten ulaşmaya çalıştığımız servisin adresi demek.

İlk satırda Uri'mizi yaratırken App.Current.Host.Source ile XAP dosyasının yerinin tam web adresini almış oluyoruz. Bizim örneğimizde web servisi XAP dosyası ile aynı konumda değil bir üst klasörde yer aldığı için bir üst klasörü çıkıp web servisimize ulaşabiliriz.

Binding'imizi de standart olarak yarattıken sonra Endpoint yaratıp parametre olarak Uri'mizi veriyoruz. Son olarak eldeki binding ve endpointler ile servisimizin proxy'sinden bir Client nesnesi alıp proje içerisinde rahatlıkla kullanabiliriz. Böylelikle SL uygulaması her açıldığında bulunduğu adrese bakıp ona göre web servisine yönelip sizin Visual Studio içerisinde service referecen eklerken kullandığınız hedef adresin hiçbir önemi kalmayacaktır.

Hepinize kolay gelsin.

Saturday, September 05, 2009 12:27:06 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 3.0  | 
 Friday, September 04, 2009

İster AJAX sitelerinde olsun ister Silverlight bir şekilde istemci tarafında sayfanın manipüle edildiği web uygulamalarındaki dertlerden biri URL'in değişmiyor olması ile beraber tarayıcı geçmişinin de çalışamaması. İlk bakışta belki büyük bir sorun gibi gözükmese de müşterilerinize teslim ettiğiniz bu gibi projelerin sonrasında aldığınız geri dönüşler emin olun sizi bu konuda ciddi şekilde şaşırtabilir.

Navigation API ile sorunlara çözüm....

Silverlight uygulamaları içerisindeki Navigation konseptini çözmeyi hedefleyen Navigation kontrolleri ve API aynı anda yukarıdak bahsettiğimiz URL'in duruma göre değişebilmesi ve hatta istemci taraflı URLReWriting yapılabilmesini de sağlıyor. Bu çerçevede yeni bir Silverlight projesi yaratarak adım adım ilerleyelim.

İlk olarak uygulamanızda Navigation API kullanacaksanız hemen System.Windows.Controls.Navigation assembly'sini referans olarak almanız gerekiyor. Bu assembly içerisinde kullanacağımız sınıflar ve kontroller bulunuyor. Navigation sistemine kendine has bir Frame ve Page yapısına sahip. Uygulamanızda navigasyon uygulamak istediğiniz ana bir sayfa belirledikten sonra bu sayfa içerisinde Frame kontrolünü yerleştiriyorsunuz. Sonrasında bu Frame içerisine farklı Page kontrollerini yükleyebilirsiniz. Aslında bu yapı bizim eski klasik HTML'den alıştığımız IFRAME'e çok benziyor tek farkı özünde tamamen Silvelright içerisinde bir yapı olması.

Yarattığımız yeni Silverlight uygulamasında gerekli DLL'leri referans aldıktan sonra ana sayfa olarak varsayılan ayarlarla gelen MainPage.xaml UserControl'ünü kullanacağız. Bu UserControl içerisine bir Frame kontrolü yerleştirmemiz gerekiyor.

[XAML]

<UserControl x:Class="SilverlightApplication4.MainPage"

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

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

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

   mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">

        <navigation:Frame x:Name="BirFrame" Source="/AnaSayfa.xaml">

        </navigation:Frame>

    </Grid>

</UserControl>

System.Windows.Controls namespace'in eklenen kontrollerden biri olan Frame kontrolü doğrudan System.Windows.Controls.Navigation assembly'si üzerinden geliyor. Gerekli XML namespace'lerini de Usercontrol çapında tanımladıktan sonra rahatlıkla söz konusu namespace üzerinden Frame kontrolünü yaratabiliyoruz. Tabi bu Frame'in ilk açılışta göstereceği Page'in adresini de Source olarak vermeniz gerekiyor.

Tüm bu hikaye içerisinde farkındaysanız bir UserControl bir Page diye iki farklı şeyden bahsediyorum. UserControl'ler bizim normal şartlarda kullandığımız hem ana sayfalarımız hem iç User Controllerimiz vs olabiliyor. Silverlight içerisinde ana uygulama görseli de sonuç olacak bir UserControl. Fakat söz konusu Navigation API olunca bir Frame içerisinde ancak Page kontrollerini gösterebiliyorsunuz. Page kontrollerinin özünde UserControl'lerden bir eksiği yok fazlası var. O nedenle bir UserControl içerisinde yapabildiğiniz herşeyi Page içerisinde yapabileceğinizi unutmayın.

Şimdi gelin bir de basit Page yaratıp adını AnaSayfa.xaml yapalım ki yukarıdaki uygulamamız rahatlıkla çalışsın. Projenizde "Add new item" dediğiniz "Silverlight Page" seçeneği ile karşılaşacaksınız.

[XAML]

<navigation:Page x:Class="SilverlightApplication4.AnaSayfa"

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

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

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

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

          mc:Ignorable="d"

          xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

          d:DesignWidth="640" d:DesignHeight="480"

          Title="AnaSayfa Page">

    <Grid x:Name="LayoutRoot">

 

    </Grid>

</navigation:Page>

Gördüğünüz gibi Page kontrolleri de yine System.Windows.Controls.Navigation altından geliyor. Bir Page kontrolünün Title özelliği uygulama tarayıcıda açıkken tarayıcının işletim sistemine ait üst çubuğunda gözükecek olan içeriği tanımlıyor. Böylece Frame içerisindeki Page'ler değiştikçe her Page kendi Title bilgisini tarayıcının çubuğuna aktarabiliyor. Sadece bu kadarla kalınmıyor aslında.

Hatırlarsanız ana sayfadaki Frame kontrolümüze Source olarak AnaSayfa.xaml demiştik. Buradan yola çıkarak Frame kontrolü ilk açıldığında Silverlight projeniz içerisinde AnaSayfa.xaml'ı yükleyecektir. Sonrasında başka bir sayfaya yönlendirme yapmak isterseniz bunu ana sayfanızdaki bir HyperlinkButton ile rahatlıkla yapabilirsiniz.

[XAML]

<UserControl x:Class="SilverlightApplication4.MainPage"

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

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

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

   mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">

        <StackPanel>

            <navigation:Frame Height="300" x:Name="BirFrame" Source="/AnaSayfa.xaml">

            </navigation:Frame>

            <HyperlinkButton x:Name="Link1" NavigateUri="/BaskaSayfa.xaml" TargetName="BirFrame" Content="TIKLA"/>

        </StackPanel>

    </Grid>

</UserControl>

Yukarıdaki örnekte gördüğünüz HyperlinkButton'un TargetName özelliği çok önemli. Bu özelliğe aktarılan isim bizim Frame kontrolünün ismi olduğu için kontrol içerisindeki linkin doğrudan Silverlight içerisindeki Frame'e yönlendirileceği anlaşılabiliyor. HyperlinkButton'ın NavigateUri özelliğinde ise Silvelright uygulaması içerisindeki bir diğer Page kontrolünün adresi bulunuyor. Bu adresler Silverlight uygulamasının rootuna göre veriliyor. Yukarıdaki HyperlinkButton'a tıklandığıda otomatik olarak hedef Page Frame içerisinde yüklenecektir.

Tüm bu işlemler gerçekleşirken Navigation API sizin yerinize tarayıcının adres çubuğunda da gerekli değişiklikleri otomatik olarak yapacaktır.

Uygulama ilk açıldığında adresi:
http://localhost:2593/SilverlightApplication4TestPage.html#/AnaSayfa.xaml

HyperlinkButton'a tıkladıktan sonraki adres:
http://localhost:2593/SilverlightApplication4TestPage.html#/BaskaSayfa.xaml

Yukarıdaki adresler arasındaki farklarda da görebileceğiniz üzere Frame içerisine yüklenen her kontrolün adresi tarayıcının da adres çubuğunda bulunuyor. Bu adresler birer Fragment olarak implemente edildiği için tarayıcı herhangi bir şekilde sayfaya refresh atmasa da bu değişiklikleri tarayıcı geçmişine kaydedebilecektir. Böylece rahatlıkla kullanıcılar tarayıcıların "İleri" ve "Geri" düğmeleri kullanarak uygulamamız içerisinde gezebilecekler. Bu sistemin bir diğer avantajı da kullanıcıların uygulamamızla ilgili farklı sayfaların linklerini alarak arkadaşlarına gönderebilecek olmaları. Bu adresler eğer kopyalanıp farklı bir makineden farklı bir tarayıcıda doğrudan çalıştırılırsa Navigation API uygun Page'i Frame içerisine otomatik olarak yükleyecektir.

Page'lere parametre nasıl göndeririz?

Belki de Page'leri Frame içerisine yüklerken parametreler göndermek isteyeceksiniz. Hatta belki de bir Page'in kendi içerisinde bulunduğu Frame'e başka bir Page'i yüklemesini söyleyebilmesini isteyeceksiniz. Biraz karışık oldu değil mi? Gelin tek tek bu soruları da cevaplayalım. İlk olarak ana sayfadan değil de bir Page'in kendi içinden navigasyon sağlamanın yoluna bakalım.

[VB]

    Private Sub btntikla_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btntikla.Click

        Me.NavigationService.Navigate(New Uri(String.Format("/Urun.xaml?ID={0}", 1), UriKind.Relative))

    End Sub

Yukarıdaki kod doğrudan Frame içerisinde bir Page'in içindeki düğmeye bağlı. Ana sayfada Frame'e ulaşarak "sen bu adresi aç" demek kolay fakat Frame içerisinde bir Page'i kendi sahibi olan Frame'e böyle bir komut gönderebilmesi için her Page içerisinde otomatik olarak yer alan NavigationService'i kullanmamız gerekiyor. NavigationService üzerinden çağırdığınız Navigate metoduna her zamanki gibi Silverlight uygulamanız içerisindeki bir başka Page'in adresini verebilirsiniz.

Yukarıda yönlendirme yaptığımız adrese dikkat ettiyseniz sonunda bir parametre var. Sanki normal bir web sitesinde yönlendirme yaparmış gibi QueryString üzerinden parametre gönderebiliyoruz. Tabi söz konusu Urun.Xaml adındaki Page'in de bu parametreyi okuyabilmesi gerekiyor.

[VB]

Partial Public Class Urun

    Inherits Page

 

    Public Sub New()

        InitializeComponent()

    End Sub

 

    'Executes when the user navigates to this page.

    Protected Overrides Sub OnNavigatedTo(ByVal e As System.Windows.Navigation.NavigationEventArgs)

        If Me.NavigationContext.QueryString.ContainsKey("ID") Then

            GelenParametre.Text = Me.NavigationContext.QueryString("ID")

        End If

    End Sub

 

End Class

Urun.xaml adındaki Page'imizin için otomatik olarak gelen OnNavigateTo metodu söz konusu Page ekrana geldiğinde çalışacaktır. Kontrol ekrana geldiğinde hemen gidip kendisine QueryString üzerinden bir ID gönderilip gönderilmediğini kontrol etmemiz gerek. Bunun için yine her Page'de bulunan NavigationContext'i kullanıyoruz.

NavigationContext'in altındaki QueryString nesnesinin ContainsKey özelliği ile ID parametresinin gelip gelmediğini kontrol ettikten sonra QueryString Dictionary'sine doğrudan elimizdeki key'i verip değeri alabiliyoruz. Böylece hazırladığınız bir Page'i Frame içerisine yüklerken ona bir parametre gönderip onun da parametreye uygun verileri göstermesini veya uygun işlemleri yapmasını sağlayabilirsiniz.

UriMapping işlemleri.

Şu ana kadar yaptığımız tüm işlemlerde verdiğimiz Frame adresleri otomatik olarak adres çubuğuna yazıldı. Bu durumun birçok avantajı var. Fakat ortada hoş olmayan bir konu var ki o da herşeyin alenen ve çirkin bir şekilde adres çubuğunda gözüküyor olması. Örneğin aşağıdaki adres bizim Urun.xaml'a parametre gönderdiğimize oluşan adres.

http://localhost:2593/SilverlightApplication4TestPage.html#/Urun.xaml?ID=1

Bu sorun tanıdık geliyor değil mi? Aslında biz bu sorunu yıllarda web uygulamalarında da yaşadık ve UrlReWriting kullanarak daha hoş URL'lere sahip olmayı öğrendik. İşte aynı sistemi Navigation API içerisinde de UriMapper kontrolleri ile sağlayabiliyorsunuz.

[XAML]

<UserControl x:Class="SilverlightApplication4.MainPage"

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

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

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

            xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"

            xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"

   mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">

    <Grid x:Name="LayoutRoot">

        <StackPanel>

            <navigation:Frame Height="300" x:Name="BirFrame" Source="/AnaSayfa">

                <navigation:Frame.UriMapper>

                    <uriMapper:UriMapper>

                        <uriMapper:UriMapping Uri="" MappedUri="/AnaSayfa.xaml"/>

                        <uriMapper:UriMapping Uri="/{SayfaAdi}" MappedUri="/{SayfaAdi}.xaml"/>

                    </uriMapper:UriMapper>

                </navigation:Frame.UriMapper>

            </navigation:Frame>

            <HyperlinkButton x:Name="Link1" NavigateUri="/BaskaSayfa" TargetName="BirFrame" Content="TIKLA"/>

        </StackPanel>

    </Grid>

</UserControl>

uriMapper kontrolünü kullanabilmek için ayrı bir XAML namespace tanımlayarak bu sefer de System.Windows.Controls.Navigation'ı import etmemiz gerekiyor. Sonrasında uriMapper kontrolünü yaratarak doğrudan Frame'in UriMapper özelliğine verebiliyoruz. UriMapper kendi içerisinde UriMapping kontrolleri kullanıyor.  Her uriMapping'in bir Uri ve bir de MappedUri özelliği var.

[XAML]

                        <uriMapper:UriMapping Uri="" MappedUri="/AnaSayfa.xaml"/>

                        <uriMapper:UriMapping Uri="/{SayfaAdi}" MappedUri="/{SayfaAdi}.xaml"/>

Örneğimizdeki bu iki kodu incelersek ilkinde boş bir adres geldiğinde açılarak kontrolün adresine yönlendirildiğini görebiliriz. İkincisinde ise bir değişken kullanılmış durumda. SayfaAdi adını verdiğimiz bu değişkeni gelen adresten alıp sonuna .xaml uzantısını ekleyip yönlendiriyoruz. Böylece bir önceki adımdaki URL'lerimiz ile şu ankiler çok daha farklı olabiliyor.

Uygulama ilk açıldığında adresi:
http://localhost:2593/SilverlightApplication4TestPage.html#/AnaSayfa

HyperlinkButton'a tıkladıktan sonraki adres:
http://localhost:2593/SilverlightApplication4TestPage.html#/BaskaSayfa

Eğer kodumuzda dikkat ettiyseniz artık HyperlinkButton'un NavigateUri'sinde BaskaSayfa.xaml yazmıyor, doğrudan sadece BaskaSayfa yazıyor. Artık sondaki .xaml uzantıları Mapper tarafından halledilecek. Bu şekilde QueryString parametrelerini de map edebilirsiniz.

[XAML]

                    <uriMapper:UriMapper>

                        <uriMapper:UriMapping Uri="" MappedUri="/AnaSayfa.xaml"/>

                        <uriMapper:UriMapping Uri="/Urun/{ID}" MappedUri="/Urun.xaml?ID={ID}"/>

                        <uriMapper:UriMapping Uri="/{SayfaAdi}" MappedUri="/{SayfaAdi}.xaml"/>                       

                    </uriMapper:UriMapper>

Yukarıdaki ek Mapping sayesinde artık Urun/2 şeklinde gelen adresler doğrudan Urun.xaml?ID=2 şekline dönüştürülecek.

UriMapping öncesi:
http://localhost:2593/SilverlightApplication4TestPage.html#/Urun.xaml?ID=2

UriMapping sonrası:
http://localhost:2593/SilverlightApplication4TestPage.html#/Urun/2

Gördüğünüz gibi Naviation API gerçekten kuvvetli bir altyapı sunuyor. Tüm bu altyapının her noktasına ayrı ayrı müdahale edebiliyorsunuz. Mantık olarak çok yabancı olmadığımız bir kullanım şekli olduğu da kesin.

Hepinize kolay gelsin.

Friday, September 04, 2009 5:44:56 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 3.0  | 
 Thursday, September 03, 2009

İster Silverlight tarafında olsun ister WPF teknolojinin ve araçların sürekli bahsedilen en önemli özelliklerinden biri tasarımcı ile yazılımcı arasındaki ilişkiyi düzenlediği yönünde. Tabi ki eskisine kıyasla çok sayıda artı özellik bu iki profil arasındaki "kavgaların" azalmasını sağlıyor fakat diğer yandan özellikle yazılımcının da Expression Blend uyumlu binding yapılabilir nesnelerini tanımlayabiliyor olması çok önemli. Tabi aynı derecede bir tasarımcının da Blend içerisinden yola çıkarak programcının arka planda kendisine sağladığı CLR nesnelerine ulaşabilmesi şart.

Tüm bu senaryo ile ilgili ufak bir örnek yapacağımız bu yazımızda ilk olarak bir programcı olarak tasarımcının uygulama tasarımında istediği gibi işlevsellikleri ayarlayabileceği ve binding'leri set ederek hangi datanın nerede gözükeceğine karar verebileceği bir altyapı oluşturacağız. Sonrasonda tasarımcı profili ile Expression Blend'e geçerek arka tarafta programcının hazırlamış olduğu nesneleri alıp uygulama arayüzünde istediğimiz yerlere yerleştireceğiz.

Visual Studio tarafından başlayalım!

Varsayalım ki elinizde bir Insan listesi var ve bunu bir şekilde tasarımcının ellerine aktarmak istiyorsunuz. Sizin bir programcı olarak yapmanız gereken bu listeyi bir veri kaynağından alıp (bu ister SQL ister başka bir kaynak olabilir) Expression Blend tarafında kullanılabilir hale getirmek. Yani verinizin User Interface tarafında kullanılabilmesini sağlamanız gerekiyor. İlk olarak gelin basit bir şekilde Insan nesnemizi tanımlayalım.

[VB]

Public Class Insan

 

    Private _Soyadi As String

    Public Property Soyadi() As String

        Get

            Return _Soyadi

        End Get

        Set(ByVal value As String)

            _Soyadi = value

        End Set

    End Property

 

 

    Private _Adi As String

    Public Property Adi() As String

        Get

            Return _Adi

        End Get

        Set(ByVal value As String)

            _Adi = value

        End Set

    End Property

 

End Class

Gördüğünüz gibi nesnemizin şimdilik iki basit özelliği var. Amacımız bu nesneden birden çok sayıda yaratıp bir liste olarak tasarımcıya aktarmak. Bunun için ayrı bir sınıf tanımlamamız uygun olur. Söz konusu sınıf içerisinde de ObservableCollection dönecek bir metod yer alacak.

[VB]

Public Class AllData

 

    Private _All As New System.Collections.ObjectModel.ObservableCollection(Of Insan)

    Public Property All() As System.Collections.ObjectModel.ObservableCollection(Of Insan)

        Get

            Return _All

        End Get

        Set(ByVal value As System.Collections.ObjectModel.ObservableCollection(Of Insan))

            _All = value

        End Set

    End Property

 

    Sub New()

        _All.Add(New Insan() With {.Adi = "1asdasd", .Soyadi = "2222"})

        _All.Add(New Insan() With {.Adi = "2asdasd", .Soyadi = "4222"})

        _All.Add(New Insan() With {.Adi = "3asdasd", .Soyadi = "5222"})

        _All.Add(New Insan() With {.Adi = "4asdasd", .Soyadi = "6222"})

    End Sub

 

End Class

AllData adındaki bu sınıfın içerisinde All adında da bir Property var. Bu property geriye bir ObservableCollection döndürüyor. Bildiğiniz üzere ObservableCollection'lar TwoWay binding destekleyen collection nesneleridir. Yani görsel arayüzdeki değer değişiklikleri de otomatik olarak arka plandaki nesneye yansır. Expression Blend'de bu nesne bind edildiğinde Blend nesneyi çağırmadan önce bir Instance yani kopyasını alacaktır. İşte tam da bu kopyayı yaratırken sınıfımızın constructor'ında datamızı ObservableCollection'ımıza ekleyebiliriz. Kod yönetimi açısından tüm bu kodları harici bir VB veya C# dosyasında yazmanızda fayda var.

İşimiz bu kadar artık bu veriyi gösterme işi tasarımcının işi. Expression Blend tarafına geçerek geri kalanı bir tasarımcı profili ile yapalım.

Expression Blend tarafına geçiyoruz!

Aynı projeyi Expression Blend ile açtıktan sonra sağ barda "Data" tabını bulabilirsiniz. Data tabında "Add Live Data Source" komutunu verdikten sonra "Define New Object Data Source" diyebilirsiniz.

Expression Blend içerisinde Data Source'umuzu tanımlıyoruz.
Expression Blend içerisinde Data Source'umuzu tanımlıyoruz.

Karşınızda çıkacak ekranda AllData adındaki sınıfımızı seçmeniz yeni DataSource'u yaratmanız için yeterli olacaktır. Artık sıra geldi bu DataSource içerisinde hangi Property'yi nasıl kullanacağınıza.

Nesnelerimiz Expression Blend tarafından algılandı.
Nesnelerimiz Expression Blend tarafından algılandı.

Artık Data tabındaki veri kaynağı ile ilgili tüm detayları görebiliriz. Tasarımcı olarak Data tabından veriyi sahneye koymak için birkaç yolumuz var. Bunlardan ilki liste görünüşünü kullanmak. Şu an yukarıdaki ekran görüntüsünde List Mode gözüküyor. Bu durumda ObservableCollection'ı alıp sahneye bıraktığınızda otomatik olarak bir ListBox yaratılacak ve veri ListBox'a bağlanacaktır.

Sürükle, bırak! Ve karşında ListBox!
Sürükle, bırak! Ve karşında ListBox!

Artık bu ListBox'ın ItemTemplate'inin vs tasarımını değiştirmek tabi ki makalemizin sınırları dışında. Fakat unutmamak gerek ki artık canlı veriye bağlı ve tamamiyle tasarımı özelleştirilebilir bir ListBox tasarımcımızın ellerinde. Ayrıca tek seçenek ListBox da değil. Eğer sahnede bir Grid veya başka bir kontrol olsaydı doğrudan Collection'ı onun üzerine sürükleyip bırakarak da Data Binding işlemi rahatlıkla yapılabilirdi.

Details Mode karşınızda.
Details Mode karşınızda.

List Mode'un yanı sıra Blend içerisinde kullanabileceğimiz bir diğer Data modu da Details Mode olarak karşımıza çıkıyor. Bu moddayken veri kaynağından nesneleri ancak Property'ler olarak sürükleyip bırakabilirsiniz çünkü artık amacınız bir liste göstermek değil. Artık amacımız nesnelerin detaylarınız göstermek. Tek tek her Property'yi sahnedek ayrı nesnelere Bind edebileceğiniz gibi nesnelerin yaratılmasını Blend'e de bırakabilirsiniz. Örneğin gelin hem Adi hem de Soyadi Property'lerini seçerek sahneye sürükleyip bırakalım.

Details Mode ile otomatik detay görünümü yaratabilirsiniz.
Details Mode ile otomatik detay görünümü yaratabilirsiniz.

Gördüğünüz gibi sürükle bırak sonrasında otomatik olarak bir Grid yaratılarak içerisinde hem Property isimlerini taşıyan hem de değerleri taşıyan birer TextBlock yerleştirildi. İşin en güzel tarafı binding işlemini aynı nesne kopyasına yaptığımız için ListBox içerisinde hangi nesne seçilirse onun detaylarının bu Grid içerisinde gösterilecek olması. Yani tüm işlevsellik tamamlanmış durumda!

Arka planda Blend neler yaptı?

Blend aslında basit bir şekilde Binding mekanizmalarının tasarımcılar tarafında rahatlıkla kullanılabilmesini sağlıyor. Maalesef şu an için bu mekanizmaları yazılımcılar olarak bizim elle yazmaktan başka şansımız ki. Visual Studio 2010 ile bu durumda toparlanacak ve bizler de tüm bu ayarları yapabileceğimiz menülere sahip olacağız.

XAML tarafına bir göz atacak olursak dikkatimizi çeken birkaç nokta olabilir.

[XAML]

<UserControl

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

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

   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

   mc:Ignorable="d" xmlns:local="clr-namespace:SilverlightApplication2" xmlns:dataFormToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" x:Class="SilverlightApplication2.MainPage"

   d:DesignWidth="640" d:DesignHeight="480">

    <UserControl.Resources>

        <local:AllData x:Key="AllDataDataSource" d:IsDataSource="True"/>

        <DataTemplate x:Key="InsanTemplate">

            <StackPanel>

                <TextBlock Text="{Binding Adi}"/>

                <TextBlock Text="{Binding Soyadi}"/>

            </StackPanel>

        </DataTemplate>

    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource AllDataDataSource}}" >

        <ListBox x:Name="listBox" Margin="47,96,0,84" ItemTemplate="{StaticResource InsanTemplate}" ItemsSource="{Binding All}" HorizontalAlignment="Left" Width="200"/>

        <Grid DataContext="{Binding SelectedItem, ElementName=listBox}" Margin="310,94,76,186" d:DataContext="{Binding All[0]}" Background="White">

            <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="16" Text="Adi"/>

            <TextBlock Text="{Binding Adi}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Height="16" Margin="104,0,0,0"/>

            <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="16" Margin="0,20,0,0" Text="Soyadi"/>

            <TextBlock Text="{Binding Soyadi}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Height="16" Margin="104,20,0,0"/>

        </Grid>

    </Grid>

</UserControl>

Yukarıda tüm uygulamanın XAML kodunu inceleyebilirsiniz. Özellikle renkli kısımlara bakacak olursak Blend'in neler yapmaya çalıştığını net bir şekilde görebiliriz. İlk olarak en üstte bizim arkadaki uygulamamızın bir XML namespace olarak Import edilmiş. Sonra söz konusu yerden AllData sınıfından bir instance alınıp Resrouce'lar arasına AllDataDataSource adı ile koyulmuş. Bu DataSource uygulama genelinde Grid'e bağlanmış. Grid içerisinde ListBox ise All metoduna bağlanmış. ListBox aldığı her Insan nesnesini yine Resource'lar içerisinde tanımlı InstanTemplate ile gösterebiliyor. InsanTemplate içerisinde ise her Insan'ın Property'leri uygun kontrollere bağlanmış durumda. Son olarak detayları gösterecek olan nesnelerin bulunduğu Grid'in DataContext'i bizim ListBox'ın SelectedItem'ına element binding ile bağlanmış. SelectedItem zaten bir Insan nesnesi olarak geleceğine göre Grid içerisindeki kontrolleri de doğrudan bu Insan nesnesinin Property'lerine bağlayabiliriz. Son ufak bir detay ise Grid'in DataContext'inin yanı sıra bir de d:DataContext diye bir Property'sinin All listesindeki Index numarası sıfır olan kayda bind edilmiş olması. d: XML namespace'i tamamen design view için gerekli özellikleri tanımlar. Yani tasarımcı Blend içerisinde uygulamayı görürken ve uygulama çalışmazken bu Grid'in doğrudan All listesindeki ilk nesneyi göstermesini sağlamak için Blend böyle bir kod eklemiş durumda.

Sonuç olarak gördüğünüz gibi aslında her iki tarafın da kurallara uyması halinde Expression Blend ve Visual Studio ile beraber tasarımcılar ve yazılımcıların beraber rahatça çalışması olması.

Hepinize kolay gelsin.

Thursday, September 03, 2009 5:43:47 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Expression Blend | Silverlight 3.0  | 
 Wednesday, September 02, 2009

DVD veya CD arayüzleri hala bilgisayar dünyasında ciddi bir yere sahip. İçeriğin paylaşımı adında internet ciddi bir yol almış olsa da hala CD ve DVD medyalarını kullanarak içeriğin dağıtımı bazı senaryolarda çok daha işlevsel olabiliyor. Bu gibi durumlarda doğal olarak bir arayüz ile söz konusu içeriği bir CD veya DVD içerisinde sunmak gerekiyor. Peki bu arayüzü geliştirmek için hangi teknolojileri kullanabiliriz?

Gelin beraberce sıralayalım;

HTML - Pufff!
Flash - ActionScript? Pufff!
WPF - .NET Framework yükletmek? Puff!
Silverlight - Oley! İşte bu!

Şaka bir yana :) aslında bir CD veya DVD arayüzü geliştirirken ihtiyacımız olan şey hem arayüz içerisinde her tür data işlemini yapabilimek hem de güzel bir arayüz tasarlayabilmektir. Varsayalım bir ürün kataloğu yapıyorsunuz, büyük ihtimal ile söz konusu ürünler arasında arayüzde arama da yapılabilmelidir. İşte ufak da olsa bir programlama noktası karşımızda. Olabildiğince rahat programlamak ve bildiğimiz bir dili kullanmak önemli. HTML ile JavaScript veya Flash ile ActionScript bir .NET developer için çok da ferah bir gelecek vaadetmeyecektir. Ayrıca HTML ile zaten güzel bir arayüz, zengin bir kullanıcı deneyimi sağlamak da pek mümkün değil.

Alternatiflerden bir diğeri WPF olabilir ve aslında çok da güzel olur. Fakat bu sefer de .NET Framework gereksinimi ile karşı karşıya kalıyoruz. Eh hadi DVD'nin içine koyalım ama insanların bir DVD arayüzünü görebilmek için .NET Framework kurup (en az 5dk) makinelerine restart atacaklarından emin misiniz?

Tüm bu senaryonda en güzeli Silverlight! Hem bildiğimiz VB, C# hem Expression Blend ile süper kullanıcı deneyimi hem de 4MB Runtime ve 5 saniye yükleme süresi. Hem MAC desteği de var! Eh gönül daha ne ister?

Tamam da şimdi tarayıcıda açtırmak da pek hoş olmuyor!

Kesinlikle! Bir CD veya DVD arayüzünün tarayıcı içerisinde açılması benim en uyuz olduğum noktalardan birisidir özünde. Neden mi? Çünkü ister istemez bir web sitesi hissiyatı yaratıyorsunuz ve en azından bende "çok uğraşılmamış" efekti oluşturuyor. Yani "adamlar web sitesi yapıp koymuş DVD'ye!" gibi abuk bir yorumun gelmesi olasılığı ciddi yüksek. O nedenle tarayıcıdan kurtulmamız gerek.

HTML Application = HTA!

HTA'larla ilk tanışdığımda "İşte bu" demiştim :) Sanırım SQL 2000'in yükleme CD'sinin arayüzünde görmüştüm. Arayüz ilgimi çekmişti çünkü bir tarayıcı gibi içinde HTML olduğunu hissetmiş fakat ortada bir tarayıcı görmemenin de şaşkınlığını yaşamıştım. Sonra biraz CD'yi karıştırınca HTA'larla tanıştım. HTA aslında HTML vs bir scripting dili ile yazılabilir uygulamalar şeklinde tanımlanabilir. Bu uygulamalar "Microsoft HTML Applicatio Host" adında özel bir uygulama tarafından Windows içerisinde host edilir. Arka planda Internet Explorer kullanılır fakat kullanıcılar bunu görmez. HTA uzantılı bir dosya rahatlıkla Notepad ile açılabilen birer HTML dosyasıdır aslında.

[HTA]

<HTML>

  <head>

  <link href="img/styles.css" type="text/css" rel="stylesheet" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <TITLE>

      Internet Explorer 8 -DVD

    </TITLE>

 

    <HTA:APPLICATION

     APPLICATIONNAME="IE8DVD" 

     MAXIMIZEBUTTON="no"

     MINIMIZEBUTTON="no"

     SINGLEINSTANCE="yes"

     ICON="setup.ico"

     SCROLL="no" />

  </HEAD>

 

<body style="margin:0px;">

 

    <script for="window" event="onload">

   window.resizeTo(820,640);

   window.moveTo((screen.width - 820) / 2, (screen.height - 640) / 2);

</script>

</body>

</html>

Yukarıda gördüğünüz kod basit bir HTA dosyasının içeriği. Aslında içerisinde pek birşey yok. İlk anlamamız gereken şey aslında bir HTML ile çalışıyor olduğumuz. Tabi biz arayüzü oluşturmak için HTML değil Silverlight kullanacağız. Önemli olan ilk şey tabi ki dokümanın TITLE kısmını ayarlamak çünkü bu uygulamanızın açılan penceresinin başlığı olacak. Aşağıda gördükleriniz ise uygulama parametreleri.

[HTA]

    <HTA:APPLICATION

     APPLICATIONNAME="IE8DVD" 

     MAXIMIZEBUTTON="no"

     MINIMIZEBUTTON="no"

     SINGLEINSTANCE="yes"

     ICON="setup.ico"

     SCROLL="no" />

Uygulamanın açılacağı pencerede pencereyi büyütme, küçültme vs gibi düğmeleri isteyip istemediğinizi belirtebilir hatta uygulamanın tek oturumunun olmasını da yukarıdaki parametreler ile sağlayabilirsiniz. Uygulama ikonunu da ayarladıktan sonra önemli noktalardan biri Scroll özelliği NO şeklinde set etmek. Malum biz bu HTML içerisinde arayüz olarak Silverlight koyacağımız için zaten gerekli scroll işlemlerini de SL içerisinde halledebiliriz.

[HTA]

    <script for="window" event="onload">

   window.resizeTo(820,640);

   window.moveTo((screen.width - 820) / 2, (screen.height - 640) / 2);

</script>

Yukarda basit bir JavaScript kodu görüyorsunuz. Bu kod uygulamanızın penceresinin boyutunu ayarlayacağı gibi pencerenin de ekranın tam ortasında gözükmesini sağlayacaktır. HTA'lar içerisinde hem JavaScript hem VBScript kullanabilirsiniz. Her script ait olduğu nesneye for özelliği ve ait olduğu nesnenin hangi event'ını dinleyeceğine de event parametresi ile bağlanır.

Bu noktadan sonra tabi ki sizin ilk olarak Silverlight uygulamanızı hazırlamanız gerek. Arayüz olarak kullanılacak Silverlight uygulaması hazırlandıktan sonra bu HTA içerisine uygun şekilde yerleştirilebilmesi çok önemli.

[HTA]

<HTML>

  <head>

  <link href="img/styles.css" type="text/css" rel="stylesheet" />

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <TITLE>

      Internet Explorer 8 -DVD

    </TITLE>

 

    <HTA:APPLICATION

     APPLICATIONNAME="IE8DVD" 

     MAXIMIZEBUTTON="no"

     MINIMIZEBUTTON="no"

     SINGLEINSTANCE="yes"

     ICON="setup.ico"

     SCROLL="no" />

  </HEAD>

 

<body style="margin:0px;">

    <div id="silverlightControlHost">

        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">

            <param name="source" value="ClientBin/Interface.xap"/>

            <param name="background" value="white" />

            <param name="minRuntimeVersion" value="2.0.31005.0" />

            <param name="autoUpgrade" value="true" />

            <img style="cursor:pointer;" ID="SLInstall" border="0" src="images/install.jpg" />

        </object>

    </div>

 

    <script for="window" event="onload">

   window.resizeTo(820,640);

   window.moveTo((screen.width - 820) / 2, (screen.height - 640) / 2);

</script>

     <SCRIPT FOR="SLInstall" EVENT="onclick" LANGUAGE="VBScript">

      Dim objShell

      Dim lngReturn

 

      on error resume next

 

      set objShell = CreateObject( "WScript.Shell" )

 

        lngReturn = objShell.Run ("Silverlight.2.0.exe", 4, 1)

 

      set objShell = Nothing

      document.execCommand("Refresh")

 

    </SCRIPT>

</body>

</html>

İşte esas noktaya geldik. Yukarı gördüğünüz OBJET tagları klasik bir SL uygulamasının bir HTML sayfaya yerleştirildiği taglardan farklı değil. Bir tek minik fark var o da OBJECT tagları içindeki HTML kodu! Hatırlarsanız tarayıcılar eğer OBJECT taglarını render edemezse içlerindeki HTML'i gösteriyorlardı. Bu gibi bir durumda Silverlight hedef makinede yüklü değilse bu demektir de tarayıcı OBJECT taglarını render edemeyecek bir OBJECT içerisindeki HTML'i kullanıcıya gösterecek.

[HTML]

      <img style="cursor:pointer;" ID="SLInstall" border="0" src="images/install.jpg" />

Yukarıdaki şekilde güzel bir resim Silverlight yüklü değilken gösterilecek resim olarak seçilebilir. Tabi bu resmin tasarımında kullanıcıya uygun mesajı bir metin olarak göstermeniz şart. Diğer yandan bu resim nesnesinin fare ile üzerine geldindiğinde el işareti gösterilmesi için uygun CSS'in kullanılması da gerekiyor. Son olarak bu IMG'ye bir de ID veriyoruz çünkü bu resme tıklandığında Silverlight Runtime yüklemesini başlatmalıyız!

[VBScript]

     <SCRIPT FOR="SLInstall" EVENT="onclick" LANGUAGE="VBScript">

      Dim objShell

      Dim lngReturn

 

      on error resume next

 

      set objShell = CreateObject( "WScript.Shell" )

 

        lngReturn = objShell.Run ("Silverlight.2.0.exe", 4, 1)

 

      set objShell = Nothing

      document.execCommand("Refresh")

 

    </SCRIPT>

Yukarıda bir VBScript kodu görüyorsunuz. Silverlight Runtime yüklemesine ait EXE dosyasının HTA ile aynı klasöre koyduktan sonra uygun zamanda yüklemeyi başlatmak şart. Bunun için bir Shell nesnesi yaratarak yüklemeyi başlatabiliyoruz. Yükleme bitince de sayfaya Refresh atıyoruz böylece kullanıcı yüklemeyi yaptıktan sonra ekranı kapatıp açmadan hemen arayüzü görebiliyor. Bu scriptin FOR ve EVENT özelliklerine bakarsanız bizim bir önceki adımda yarattığımız IMG nesnesinin onclick durumunda çalışacağını görebilirsiniz.

Diskten birşey çalıştırmak istersek?

Biliyorsunuz Silverlight'ın çalıştığı makinedeki diske erişimi yok. Bunun nedeni Silverlight'ın çalıştığı yer olan tarayıcı içerisindeki alandan yani bir web sitesinden de hedef makinedeki diske ulaşamıyor olmamız. HTA'lar bu konuda biraz farklılar. HTA'larda rahatlıkla diske erişebilirsiniz. Aslında bir önceki örnekte biz bu işi zaten yapmadık mı? HTA içerisinden gidip Silverlight Runtime'ı yüklemek demek harici bir EXE'yi çalıştırmak demek değil mi? Aynen öyle. Peki biz bunu Silverlight içerisinden nasıl yapabiliriz?

Silverlight içerisinde çıkıp VBScript'e ulaşıp, parametre göndererek VBScript ile de diske erişebiliriz.

[VBScript]

     <SCRIPT LANGUAGE="VBScript">

             sub Getir(byval address)

      Dim objShell

      Dim lngReturn

 

      on error resume next

 

      set objShell = CreateObject( "WScript.Shell" )

 

        lngReturn = objShell.Run (address, 4, 1)

 

      set objShell = Nothing

            end sub

    </SCRIPT>

Yukarıda gördüğünüz VBScript metodu tek bir parametre alarak Shell nesnesi yaratıp parametreden gelen adresi diskte çalıştırmaya çalışıyor. Bu durumda biz bu metodu Silverlight tarafından çağırıp uygun parametreyi verebilirsek işlem tamamlanmış demektir.

[VB]

    Private Sub btnSource_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSource.Click

        System.Windows.Browser.HtmlPage.Window.Invoke("Getir", New String("samples/Hedehodo.exe"))

    End Sub

İşte bu kadar basit. Silverlight'tan DOM'a çıkarak Getir adındaki metodumuzu çalıştırıp bir de String parametre gönderiyoruz. Söz konusu String parametre aslında çalıştırmak istediğimiz uygulamanın HTA dosyasının bulunduğu yere göre relative Uri'sini içeriyor. Böylece bu parametre VBScript'e aktarılacak, oradan da Shell üzerinden çalıştırılabilecek.

Süper değil mi?

Şimdi yapabileceklerinizi bir düşünün :) Silverlight uygulaması içerisinde yapabildiğiniz herşey bir anda bir DVD arayüzüne dönüştürülebiliyor. SaveFileDialog, OpenFileDialog, Socket bağlantılar!, Desktop moduna geçip makineye anında yükleme yapabilmek! ve daha bir çok Silverlight özelliğini bir anda kullanabilir hale geliyorsunuz! Bu gerçekten muhteşem!

Wednesday, September 02, 2009 5:39:03 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   Silverlight | Silverlight 2.0 | Silverlight 3.0  | 
 Tuesday, September 01, 2009

Windows 7 ile beraber gelen ve biz yazılımcıların özellikle yeni teknolojileri test ederken kullanabileceğimiz en güzel özellik VHD'den boot etme özelliği. Malum Beta veya Alpha yazılımları normal kullandığımız makinelere yükleyemiyoruz. Oluşabilecek olası sorunlar nedeniyle bu şekilde deneme amaçtı test ortamları yaratmamız gerektiğinde kullandığımız şey sanal makineler olabiliyor. Fakat sanal makinelerde ise performans sorunları yaşıyoruz çünkü herşes sanal :) Makinenizin RAM'inden tutun CPU'suna kadar herşeyi aslında hem ana işletim sistemine hem de sunulan sanal işletim sistemine paylaştırmak zorunda kaldığımız bu seçenek çoğu zaman canımızı çıkartıyor.

Eeee yani?

Özetle artık sanal makinelere ihtiyacınız yok diyebilirim. VHD dosya formatı zaten hali hazırda VirtualPC tarafından kullanılan hard disk dosyalarını tanımlıyor. Windows 7 ile beraber bu şekilde sanal hard diskler yaratarak söz konusu hard diskler üzerinden sisteminizi boot edebiliyorsunuz. Yani düşünün ki normal makinenizde Lab.VHD adında bir dosyayı C:\ root dizininde yarattınız. Bu aslında sizin sanal makinenizin sabit diski oluyor. Sonra bu dosyanın içindeki sabit diske işletim sistemi kurup makineniz ilk açıldığında bu işletim sisteminin açılmasını sağlayabiliyorsunuz. Sanal disk üzerinden açtığınız işletim sisteminin sadece diski sanal oluyor! Diğer tüm donanım ve herşey doğrudan fiziksel donanımlarınız ile aynı! Böylece disk kısmı hariç hiçbir yerde performans kaybı yaşamıyorsunuz. İtiraf etmek gerekirse ben diskteki perfromans kaybını da testlerimde pek hissetmedim. Söylentilere göre diskteki performans kaybı %3'ün altında. Bu durumu normal sanal makineler ile karşılaştırırsak efsanevi bir performanstan bahsettiğimiz ortada.

Peki nasıl yapacağız?

İlk olarak Windows 7 DVD'nizi bilgisayarınız takıp sisteminizi baştan başlatın. DVD'den bilgisayarınızı başlattığınızda tabi ki karşınıza Windows 7 yükleme ekranı gelecek. Aman yüklemeye başlamayın :) Önce sanal diskimizi yaratmamız gerek.

Yükleme ekranında hemen "Repair" diyoruz.
Yükleme ekranında hemen "Repair" diyoruz.

Karşınıza gelen yukarıdaki ekranda hemen "Repair your computer" seçeneğini seçerek ilerleyebilirsiniz. Buradan Shift+F10 tuşlarına beraber basarak Command Prompt açmanız gerekiyor. Command Prompt açıldıktan sonra girmeniz gereken komutları sırası ile aşağıdaki şekilde;

Diskpart
Sanal sürümüzü yaratacak olan uygulamayı açar.

create vdisk file=d:\Win7Lab.vhd maximum=30000
Bu komut yeni bir sanal disk yaratacaktır.Tahmin edebileceğiniz üzere file= ile verdiğimiz parametre VHD dosyasının yaratılacağı ana diskimizdeki konum oluyor. maximum parametresinde ise yaratacağınız sanal diskin boyutunu belirtiyorsunuz. Tabi bu boyut sonuç olacak VHD dosyasının boyutu olacak ve ana diskinizde bu kadar boş alana sahip olmanız şart. Benim tavsiyem eğer diskinizde yer varsa 30GB vermeniz. 30GB rahatlıkla deneme amaçlı yükleyeceğiniz herşeyi sığdırabileceğiniz bir alan olacaktır.

select vdisk file=d:\Win7Lab.vhd
Sıra geldi bu yarattığımızı diski sistemin boot listesine eklemek. Fakat onun öncesinde tabi ki diski seçmemiz gerekiyor.

attach vdisk
İşte sanal diskimizi boot liste eklediğimiz komut burası.

Artık Command Prompt'u kapatabilirsiniz fakat sakın yükleme ekranlarını kapatmayın çünkü yeni yarattığımız sanal diske Windows7 yükleme zamanı geldi. Bu arada ufak bir hatırlatma bu şekilde sanal disk üzerinden boot edilebilecek iki işletim sistemi var; Windows 7 Ultimate, Enterprise ve Server 2008 R2. Maalesef XP vs yükleyip bu şekilde sanal disk üzerinden boot etme şansınız yok.

Windows 7 yüklemesini başlatırken "Advanced" sekmesini seçip uygun diski seçmeyi unutmayın.

Doğru diski seçmeyi unutmayın.
Doğru diski seçmeyi unutmayın.

Gördüğünüz gibi listede sanal diskimiz geliyor fakat alt tarafta da bu diske ilgili yükleme yapılamayacağına dair bir uyarı var. İşte bu uyarıyı hiç dikkat almıyorsunuz :) ve "Next" diyerek yüklemeye devam ediyorsunuz. Windows 7 birkaç defa makineniz restart atarak yüklemeyi tamamlayacaktır.

Yükleme tamamlandıktan sonra makineniz ilk açıldığında karşınızda iki tane Windows7 seçeneği gelecek :) İkisinde de "Windows 7" yazacak ve hangisinin sanal disk üzerinde hangisinin esas disk üzerinde olduğunu anlamak zor olabilir. İlk yükleme sonrasında listede en üstte gelen sanal diskin ta kendisi olacak. Fakat tabi ki bizim bu listedeki isimleri değiştirmemiz gerek ayrıca büyük ihtimal ile listede ilk sırada kendi esas Windows 7 yüklemenizin gelmesini isteyeceksiniz.

Hemen Admin hakları ile bir Command Prompt açalım ve son rötuşlarımızı yapalım.

bcdedit /v
bcdedit ile boot list üzerinde değişiklikler yapabiliyoruz. İlk yapacağımız şey tüm boot listin içeriğine göz atmak. Bu liste içerisindeki identifier'lara ihtiyacımız var.

bcdedit'ten identifier'ları alalım.
bcdedit'ten identifier'ları alalım.

Yukarıdaki listeye göz attığınız her bir identifier'ın altında bir de device bilgisi olduğunu görebilirsiniz. Device bilgilerine göz attığımızda hangisinin sanal diski gösterdiği açık ve net belli :)

bcdedit /set {identifier} description “Windows 7 Sanal Disk”
bcdedit kullanarak yukarıdaki komut ile istediğiniz bir diskin boot listedeki görünen adını değiştirebilirsiniz. Üst görseldeki listeden sanal diskimize ait boot kaydının identifier'ını alıp yukarıdaki komutun içerisinde uygun yere yerleştirmeniz yeterli olacaktır. Tabi siz kendinize özel bir description yazmayı da unutmayın.

bcdedit /displayorder {identifier} /addlast
Sıra geldi sanal diskimizin boot listesinde en sona eklemek. Hatırlarsanız ilk yükleme sonrasında sanal diskteki işletim sistemi listede en başta gelmişti. Yukarıdaki komut sanal diskin identifier'ını yerleştirerek komutu çalıştırırsanız söz konudu kayıt listenin en sonunda taşınacaktır.

bcdedit /default {identifier}
Son olarak sıra geldi varsayılan işletim sistemini değiştirmeye. Doğal olarak sistemi açtığımızda boot list geldiğinde ana işletim sistemimize ait seçeneğin seçili gelmesini isteyeceğiz. Böylece makinemizi her açtığımıda illa bir seçenek seçmemiz gerekmeyecek. Bu durumda hemen ana makinemizin identifier'ını yukarıdaki komuta ekleyerek çalıştırabiliriz.

Boot edilmek üzere VHD'miz hazır.
Boot edilmek üzere VHD'miz hazır.

Artık herşey tamam. Bilgisayarınız tekrar açtığınızda açıklaması ile ikinci sırada sanal disk üzerindeki işletim sisteminiz gelecektir. Son olarak ufak bir uyarı VHD dosyasının bulunduğu diskin BitLocker ile şifrelenmemiş olması gerekiyor aynı şekilde VHD içindeki diski de BitLocker ile şifreleme şansınız yok.

Hepinize kolay gelsin.

Tuesday, September 01, 2009 5:35:57 PM (GTB Standard Time, UTC+02:00)  #    Comments [6]   Windows 7  | 

Son beş gündür KKTC'deydim. "Silverlight Code Camp" adında EESTEC Famagusta'nın organizasyonundaki etkinlikte gönüllü eğitmen olarak yer aldım. Bu süreçte tabi ki çok da eğleceli bir beş gün geçirme şansım oldu.

Silverlight Code Camp, KKTC
Silverlight Code Camp, KKTC

Farklı ülkelerden katılımcıların bulunduğu bu uluslararası eğitimde özellikle katkısı olan sevgili Kubilay Özışık'a çok teşekkür ediyorum. Ayrıca tüm organizasyon ekibi bence süperdiniz! Bir başka etkinliklte ;) görüşmek üzere.

Tuesday, September 01, 2009 12:01:22 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 3.0  | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.