Türkçe etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Türkçe etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

Çarşamba, Mayıs 13, 2009

Asp.Net MVC Framework - Anlamak

Daha önceki MVC Framework yazılarımızda bu yapının ne işe yaradığına ne gibi uygulamalar geliştirebileceğimize göz atmıştık. Bu yazımızda ise biraz daha detaylı olarak MVC Framework ‘ü inceliyor olacağız.

MVC Framework mimari patterni üç ana katmandan oluşmaktadır. Bunlar; Model, View ve Controller ‘dır. MVC ile uygulama geliştirebilmemiz için gerekli teknik gerekliliği System.Web isim alanı türetilerek oluşturulmuş olan System.Web.MVC isim alanı geliştirilmiştir.

MVC Framework design pattern ‘ı web uygulama geliştiricilerin alışık olduğu yapıda hazırlanmıştır. Benzer sayfalar sürekli tekrarlanacaksa ya da bir sayfa üzerinde veri tabanından gelen veriler olacaksa sayfa gösterimlerinde tek tek sayfa oluşturmak yerine QueryString yapısı kullanılarak oluşturulan tek sayfa üzerinden binlerce sayfa oluşturulmuş gibi kullanılmasına olanak tanıyor. Bu yapı sayesinde artık ufak ölçekli hazırlanan web sayfalarında da bir mimari tasarım kullanılmış olacak. Geliştirilen bu yapının bizlere katkısını bir örnekle açıklamak gerekirse sanırım daha açık olacaktır.

Ufak ölçekli bir kurumun ya da kişisel web sayfası hazırlayan geliştiriciyi düşünelim. Temel site şablonları vardır. Ana sayfa, iletişim, hakkında ve bir kaç tane daha sayfa... Alt sayfalar istendiği durumda ise tek tek sayfa oluşturmaya başlanır ve statik bir site hazırlanmış olur. Zaman içerisinde bu siteye yeni eklentiler yapılmak istendiğinde ise tekrar geliştiriciye iş düşer, bir kaç sayfa daha ekler ve işini tamamlar. Fakat bu durum veya biraz daha iyi durumda bulunan sistemler zaman içerisinde başka kişiler tarafından tekrardan geliştirilmek istendiğinde geliştirilebilirliğinin olmadığını ve yeniden hazırlanması gerektiği gerçeğini ortaya çıkartır. Bu gerçek karşısında yapılması gereken katmansal mimari yapı ile tekrardan uygulama geliştirilir ve herhangi biri tarafından yenilenebilir ve belirtilen kriterler doğrultusunda büyütülebilir bir web sayfası hazırlanır. Fakat bu tür web sayfasının maliyeti ufak kurumları maalesef zorlamaktadır. Bu sebepten ötürüdür ki yukarıda bahsettiğimiz çözüme yönelerek ufak maliyetlere işlerini görecek ürünü kullanmak isterler. İşte MVC Framework bu noktada ufak maliyetlerle mimari yapıyı kullanarak uygulama geliştirmemizi sağlayan bir ürün olarak karşımıza çıkıyor. MVC ‘nin mimarisinin katmanları olan Model, Controller ve View ‘ı açıklayalım.

Model: Uygulamaya logic olarak eklenecek veri katmanını oluşturduğumuz bölümdür. Veri tabanı işlemlerimiz için tablolarımızı ve saklı yordamlarımızı (store procedure) Ado.Net Entity model veya LinQ model yardımı ile kullanabileceğimiz katman olarak tanımlayabiliriz.

View: Kullanıcı kontrollerinin, bileşenlerin gösterildiği ve son kullanıcının gördüğü katmandır. Genel olarak model katman üzerinde yer alan tablo kolonlarına göre oluşturulur. Genel yapısı dışında Asp.Net uygulamalarında da yapabildiğimiz gibi tasarımsal öğeleri ekleyerek (css, resim, animasyonlar (Flash, Silverlight, v.b. ) gibi) daha zengin web uygulamaları da oluşturabilmemiz mümkündür.

Controller: View katman üzerinde yapılan işlemler sonucunda sayfanın hangi sayfaya yönleneceğine, ya da veri tabanı üzerinde işlem mi yapacağına ilişkin işlemlerin tutulduğu katmandır.

MVC Framework kullanılarak gerçekleştirilmiş uygulamalar kompleks ( kullanıcı katmanı, iş katmanı ve veri katmanı ) yapıda oluşurlar. Bu yapı ile geliştirilen uygulamalar, en basit olarak düşünülen web sayfalarının dahi bir katmansal yapı dahilinde geliştirilmesine olanak tanıyacaktır.

Asp.Net MVC Framework ‘e alternatif uygulama nasıl gerçekleştirilir diye düşünürsek, bir Asp.Net web form uygulaması oluşturduktan sonra yukarıda açıkladığımız MVC patternine göre bir uygulama geliştirmemiz gerekecektir. Yazılım geliştirilmesinde uygulamanın iyiliğinin dışında zaman maliyetini de göze alınırsa, web formlar ve MVC patternini kullanarak geliştirdiğimiz uygulamanın aynısı daha kısa bir süre içerisinde geliştirebilmemize olanak tanıyan bir teknolojiyi tercih etmek çok daha mantıklı olacaktır. Bu sebepten ötürüdür ki web uygulamalarımızda MVC Framework ‘ü tercih etmemiz hem zaman hem de beyin gücü açısından bizlerin yararına olacaktır.

ASP.Net MVC Framework ile Web Uygulaması oluşturuyoruz…

İlk uygulamamızı oluşturmadan önce ilk olarak web sayfalarımızda ne tür yapıları kullanabileceğimize bir değinelim. MVC Framework kullanılarak geliştirilmiş olan uygulamalarda Asp.Net web sayfası ( *.aspx ), master page ( *.master ) ve user control ( *.ascx ) ‘i web projemize ekleyebiliriz. Belirttiklerimizin dışında veri tabanı tablolarını ve kolonlarını nesne olarak kullabilmemiz için özelliklerini (get ve set) tanımlayabiliriz.

MVC Framework ile uygulama geliştirebilmemiz için ilk olarak Visual Studio ‘ya eklentisinin kurulu olması gerekmektedir. Kullanmak istediğimiz model katmanına bağlı olarak ister LinQ ile hazırlanmış istersek de Ado.Net Entity Framework ‘ün olması gerekmektedir.

Bütün gereksinimlerimizin hazır olduğunu düşünerek MVC Framework projesi geliştirmeye başlayabiliriz. İlk olarak yeni bir MVC projesi oluşturmamız gerekmektedir. Bu işlem için new-> Project -> ASP.NET MVC Web Application adımlarını izleyerek projemizi oluşturuyoruz.



Oluşturduktan sonra test projesi de oluşturayım mı diye bir seçenek sunuyor. Bunu kabul ederek projemizi oluşturuyoruz.



Solution Explorer ‘a hangi dosyalar geldiğine göz atalım.



Projemizde oluşmuş olan klasörlerin ne işe yaradığını kısaca açıklamak gerekirse,

App_Data: Web sayfamızda kullanacak olduğumuz fiziksel veri tabanı dosyasını eklediğimiz bölümdür. SQL Express ile oluşturulan *.mdf uzantılı dosyalar bu türlerden biridir.

Content: web sayfamızda kullanacak olduğumuz style sheet, resim v.b. dosyaları tuttuğumuz klasör.

Models: Veri tabanını logic olarak kullanabilmemiz için oluşturduğumuz Entity ya da linq modeli tuttuğumuz bölüm.

Script: JavaScript, JQuery ve diğer script türlerini tuttuğumuz ve proje içerisinde referans olarak göstereceğimiz klasördür.

Views: Son kullanıcının göreceği sayfaların bulunduğu klasördür. Paylaşım dosyalarını yayınlayacaksak shared klasörünün içerisine, kullanıcı girişi v.b. işlemler yapmak istiyorsak account klasörünün içerisine. Ana ekrana ilişkin işlemler yapmak istiyorsak ta Home klasörünün içerisine ekleyebilmemiz mümkündür. Ayrıca oluşturulan web sayfalarının kendimiz oluşturabilmekle birlikte model katmanda oluşturduğumuz login model ile Controller üzerinden yaptığımız işlemler doğrultusundan otomatik olarak model a bağlı olarak oluşturabilmemiz mümkündür.

Controller: Son kullanıcılardan gelen istekleri alarak gerekli katmanlara gönderir ve tekrar son kullanıcıların görmesi için view katmanına gönderir. HomeController için düşünmek gerekirse. Ana sayfada ne tür yazılar ya da veri tabanından verilerin çekilip basıl gösterileceği home Controller ‘ da belirlenir. Hangi istek doğrultusunda oluşturmuş olduğumuz modele gideceğine ve hangi işlemi yapacağına karar verir.

HomeController kullanılarak oluşturmuş olduğumuz web sayfalarının adresi şu biçimde olmaktadır. [View]\[ControllerName]\[Action].aspx Controller üzerine bu kadar değindikten sonra yine bu konu üzerinde devam ediyor olacağız.

Controlleri Anlamak

MVC Framework kullanılmayan uygulamalarda kullanıcılardan gelen istekler doğrultusunda business katmana yönlendirme işlemini yapan bir katman durumundaydı. MVC kullanılan uygulamalarda ise kullanıcının ekranda yaptığı istekler doğrultusunda bir action olşuturulur ve işlem ona göre yapılır.

Controller içerisine, sayfalar arası yönlendirme işlemlerini, model içerisine oluşturmuş olduğumuz db logic üzerinde yapılacak işlemlerin oluşturulduğu, view katmanda oluşturulan sayfaların miraslandığı katman olarakta kabul edebiliriz.

Not: MVC Framework ‘te oluşturulan bütün Controllerlar IController arayüzünden türetilmiştir. Yani Controller sınıflarının base sınıfı IControllerdır.

Controller klasörümüzün içerisinde yer alan HomeController.cs sınıfımıza göz atarsak,

[HandleError]
public class HomeController : Controller
{
    public ActionResult Index()
    {
       ViewData["Message"] = "Welcome to ASP.NET MVC!";

       return View();
    }

    public ActionResult About()
    {
        return View();
     }
}

Yukarıdaki kod bloğunun otomatik olarak oluşturulduğunuz görürüz. HomeController sınıfı Controllerdan türetilmiş. Controller da IControllerdan türetilmektedir.

HandlerError attribute ‘ü view katmandan gelen action ‘da sorun çıkması durumunda da metodun işlemesine olanak tanımaktadır.

MVC Controller ‘da kullanabileceğimiz Public Metodlara bir göz atalım.

ViewResult: HTML ve Markup sunar (Represent).
EmptyResult: Sunumu sonlandırır.
RedirectResult: Sunulan linki yeni bir adrese yönlendirmeye yarar
JsonResult: Java Script Object ‘leri Ajax ile birlikte kullanılabilir bir duruma getirir.
JavaScriptResult: Java Script leri sayfada kullanılabilir biçimde sunar.
ContentResult: Metin içeriği sunar.
FileContentResult: İndirilebilir dosyaları sunar (Binary içerik ile).
FilePathResult: İndirilebilir dosyaları sunar (Dosya yolu ile).
FileStreamResult: İndirilebilir dosyaları sunar (Stream dosyalar için).

Şimdi de action result ile belirtilen view v.b. yönlendiren metodlara göz atalım. Aşağıda vereceğimiz bütün metodlar Controller ‘dan türetilmiştir.

View: Action sonucunda ViewResult ‘a yönlendirilir.
Redirect: Action sonucunda RedirectResult ‘a yönlendirilir.
RedirectToAction: Action sonucundan RedirectToRouteResult ‘a yönlendirilir (action yardımıyla yönlendirilir).
RedirectToRoute: Action sonucunda RedirectToRouteResult ‘a yönlendirilir (route yardımıyla yönlendirilir).
Json: JsonResult döndürür.
JavaScriptResult: JavaScriptResult döndürür.
Content: Action işlemi sonucunda ActionResult döndürür.
Controllerda yer alan metodlar yardımıyla view sayfalarda nasıl verileri gösterildiğine değiniyoruz.

public ActionResult About()
{
     return View();
}

Controllerda View sayfalarla ilişkili olan metotlara yaptığımız işlemler sonucunda son kullanıcıya verilerimizi ve istediğimiz diğer bütün içerikleri gösterebilmemiz mümkündür.

View 'ı Anlamak

View, son kullanıcıdan gelen istekleri alarak ne gibi bir işlem yapılacağına ilişkin katmana yönlendirir. Yönlendirme işlemi Controller katmanına ya da başka bir view sayfasına olmaktadır. View sayfa üzerinden db işlemlerine herhangi bir istek gönderilmemektedir. Bu işlem için ilk olarak Controller katmana yönlendirilir oradan da db model ‘e yönlendirilir. Sonrasında alınan veriler ilk olarak Controller ‘a oradan da UI yardımıyla view sayfaya gönderilir ve son kullanıcı istediği veriyi oldukça hızlı bir biçimde görmüş olur.

MVC view katmana biraz değinmek gerekirse,

1.  DB model ile direkt olarak hiçbir ilişkisi yoktur. Bu işlemler için Controller dan yararlanmaktadır.

2.  İçeriğinde, *.master, *.ascx, *.aspx ve bunlara benzer diğer dosya formatlarının kullanılması önerilmektedir.

3.  Index.aspx sayfamızı View klasörünün içerisindeki Home klasörüne eklenmesi önerilmektedir. Yani oluşturulan web sayfalarını amacına ve Controller ‘a göre klasörleyerek hazırlanması daha mantıklı bir yöntem olacaktır. Ayrıca eğer ki home klasörümüzü silerek tekrardan homeController.cs sınıfımız üzerinden oluşturmak istediğimizde Controller ‘ın önünde olan Home ismi ile bir klasör olşuturur ve içerisinde yer alan metodlardan da yararlanarak web sayfalarını oluşturur. Bu web sayfalarının *.aspx.cs dosyaları bulunmamaktadır. Controller bu bölümde yapılacak bütün işlemleri yapmaktadır.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
         To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
</asp:Content>

HomeController yardımıyla otomatik olarak oluşturulan Index.aspx sayfasının markup kodu yukarıdaki gibidir. Yukarıdaki ViewData HomeController sınıfında oluşturulan ActionResult ‘a göre işlem yapacak Index() metodu yardımı ile oluşturuştur.

View sayfada gösterilecek mesaj için Controller sınıfımızda ViewData dictionary ‘sine ekleriz. ViewPage<T> şeklinde verileri göstermektedir. T ile veri nesnesini kabul etmektedir.

Asp.Net URL Routing ‘i Anlamak

ASP.NET MVC Framework sayfalarda Controller sınıfları ile action arasındaki ilişkiyi view sayfalarla bağlantıyı URL Routing yardımı ile yapmaktadır. URL routing patterni uygulamamızın içerisinde yer alan Global.asax dosyasında yer almaktadır. Bu pattern [controller]/[action]/[id] ile yönlendirme işlemlerini yapmaktadır.

Global.asax.cs ‘in içerisinde otomatik olarak oluşturulan kod parçalarına göz atalım.

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
         routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

         routes.MapRoute(
                 "Default", // Route name
                 "{controller}/{action}/{id}", // URL with parameters
                 new { controller = "Home", action = "Index", id = "" } // Parameter defaults
                 );
    }

    protected void Application_Start()
    {
          RegisterRoutes(RouteTable.Routes);
     }
}

Biraz öncede açıklamış olduğumuz gibi Controller/Action/Id patterni ile işlemekte ve eğer ki herhangi bir istek olmazsa yani sayfa ilk açıldığında hangi sayfaya yönleneceğini belirten default url ‘da yer almaktadır.

Yazımızın bu bölümüne kadar anlattıklarımız doğrultusunda internet sayfamızı çalıştırırsak nasıl bir görünüm alacağımıza göz atalım.

Index.aspx ‘te gösterilecek veriyi ViewData dictionaryde tuttuğumuzu belirtmiştik. Bunu aşağıdaki ekran görüntüsünde görebilmeniz mümkündür.



İşlemi devam ettirip sayfamıza baktığımızda bize şu şekilde bir ekran görüntüsü sunulmaktadır.



Varsayılan URL default.aspx üzerinden yönlendirildiği için adres çubuğunda adresimiz gizlenmiş olarak gözükmektedir.

MVC Framework ‘ün ana çalışma prensibi Controller/Action/Id olduğundan defalarca bahsetmiştik. Şimdi bunun nasıl bir sonuç verdiğini görmek için About seçeneğine tıklayıp adres çıubuğuna bakmamız yeterli olacaktır.



Adres çubuğunda da gördüğünüz gibi HomeController sınıfından About metoda karşılık gelen sayfa çağırılmış.

Geldik bir yazımızın sonuna daha. Sonuç olarak nelere değindiğimize son kez göz atmak gerekirse, MVC patterninin ne olduğuna, yeni bir mvc uygulama nasıl oluşturuluyor ve bu oluşturulan uygulama hangi varsayılan dosyalar ile oluşturulduğunu detaylı bir biçimde incelemeye çalıştık.

Herkese mutlu günler diliyorum.

Cumartesi, Nisan 25, 2009

Asp.Net MVC Framework & Ado.Net Entity Framework – Veri Tabanı Uygulaması

Web uygulamalarının katmansal mimarisi olarak görülen Model View Controller yapısı 2008 yılının başlarında Microsoft tarafından MVC Framework olarak bizlere sunulacağı duyuruldu ve CTP sürümler ile nasıl kullanılacağı açıklanmaya çalışıldı. Bizlerde geçtiğimiz yıl içerisinde MVC Framework ile uygulama geliştirme nasıl olacak, hangi adımları izleyerek uygulama geliştireceğimizi anlatmaya çalıştık.

Bu yazıyı bir seri başlangıcı olarak düşünebiliriz. MVC ile ilgili “ne nasıl yapılır” diyerek yazılarımızı oluşturmaya çalışacağız. İlk yazımız olarakta Entity Framework kullanarak MVC Framework te bir veri tabanı uygulaması hazırlamak olacaktır.

Uygulamamızı Service Pack1 kurulu olan Visual Studio 2008 üzerinde geliştireceğiz. Ayrıca Ide ‘mizde MVC Framework 1.0 ‘ın da kurulu olması gerekmektedir. SP1 ‘ e olan ihtiyacımız ise Entity Framework ile tasarlayacak olduğumuz Entity Data Model ‘den kaynaklanmaktadır.

Eğer ki katmansal mimari kullanarak bir web uygulaması geliştiriyorsanız yazımızda yapacağımız örnek size çok daha aşina gelecektir. Çünkü bir Model katmanımız, Controller katmanımız ve View katmanımız olacaktır.

Yazımızda bir Film tablosu oluşturduktan sonra MVC Framework ile hazırladığımız web sayfalarında gösterme, ekleme ve düzenleme işlemlerini inceliyor olacağız. MVC Framework 'ü kullanarak uygulama nasıl oluşturulur diyerek artık örneğimize ve yazımıza başlayabiliriz.

Visual Studio 2008 ‘i açtıktan sonra File->New Project adımlarını izledikten sonra aşağıdaki ekrandan yararlanarak bir ASP.NET MVC Web Application oluşturuyoruz.



Oluşturma işlemini yap dediğimizde bize test projesi de oluşturayım mı diye soran bir ekran çıkacaktır. Biz test projesi istemiyoruz seçeneğini seçerek uygulamamıza devam ediyor olacağız.

Not: Visual Web Developers sürümünde bu ekran çıkmayacaktır.



Artık MVC uygulamamız oluşmuştur. Oluşturulan proje dosyalarını incelediğimizde bize Model, Controller ve View dosyalarının oluşturulmuş olduğunu, içeriğine de gerekli kod dosyaları ve aspx sayfalarının oluştuulduğunu görürüz. Proje dosyasında bizler biraz temizlik yapalım. Veri tabanını uygulamamıza ekledikten sonra tekrardan oluşturacağımız için;

• Controllers\HomeController.cs
• Views\Home


dosyalarını siliyoruz.

Veri tabanını oluşturuyoruz...

Örneğimizde kullanmak için bir veri tabanı oluşturmamız gerekmektedir. Bu işlemi sistemimizde kurulu olan SQL sürümüne göre değişik bir şekilde yapabilmemiz mümkündür. Bilgisayarlarında SQL Express kurulu olan arkadaşlar management studio kullanmadan direk Visual Studio üzerinden AddNewItem -> Data -> SQL DataBase adımlarını uygulayarak *.mdf uzantılı sql tabloları oluşturup üzerinde işlem yapabilmeleri mümkündür. Bir diğer adım ise SQL Server Management Studio üzerinden bir veri tabanı oluşturup onun üzerinde tablo oluşturduktan sonra visual studio üzerinde server explorer panelinden veri tabanını uygulamamıza göstererek kullanmaktadır. Biz bu seçeneklerden ikincisi üzerinde uygulamamızı geliştiriyor olacağız.

SQL Server Management Studio ‘yu açarak Sirket isimli veri tabanımızı oluşturuyoruz. Daha sonra sirket veri tabanımızın içerisine Film isimli tablomuzu aşağıdaki elemanlar ile oluşturuyoruz.



Tablomuzu ve kolonlarımızı oluşturduktan sonra Id alanını otomatik artan özelliğini atamamız gerekmektedir. Bunun için özellikler bölümünden Identity Column ‘a Id alanını veriyoruz.



Artık veri tabanımızı ve tablomuzu oluşturmuş bulunuyor. Şimdi biraz Film tablomuza daha sonraki işlemlerimizde kullanmak üzere bir kaç veri girelim.



Entity Framework ile Model Oluşturuyoruz...

Veri tabanı üzerindeki işlemlerimizi MVC uygulamamızda kullanabilmemiz veri tabanı modelini oluşturmamız gerekmektedir. Bu işlemi de Entity Data Model üzerinden yapıyor olacağız. İlk olarak oluşturmuş olduğumuz veri tabanını server explorer üzerinden visual studio ‘da kullanabilir duruma getiriyoruz.

Server Explorer üzerinde veri tabanı Connect to Database seçeneğine tıkladıktan sonra karşımıza gelen ekranda Microsoft SQL Server ‘ı seçiyoruz ve bağlantımızı ekleyeceğimiz ekrana geliyoruz. Gerekli parametreleri ekleyip veri tabanı bağlantımızı test ettikten sonra ekleme işlemini tamamlıyoruz. Eğer bu işlemi başarılı bir şekilde tamamladıysak karşımıza aşağıdaki gibi görünüm oluşacaktır.



Kullanılabilir bir veri tabanımız oluştuğuna göre model katmanımızı oluşturabiliriz. Model katman, OR/M, Nhibernate gibi toollarda çok sık bir şekilde kullanılır. MVC Framework ‘te OR/M toollarda olduğu gibi Model katmanı kullanmamazı istemektedir. Biz de bu katmanı ADO.NET Entity Framework ‘ü kullanarak oluşturacağız.

Model klasörünün üzerinde faremiz ile sağ tıklama yaparak Add -> NewItem -> Data -> ADO.NET Entity Data Model ‘i seçiyoruz.



Karşımıza geçen ekranlar sırasıyla;

1. Generate From Database
2. Choose Your Data Connection ekranında veri tabanını seçiyoruz.
3. Choose Your Database Object ekranında table seçeneğinde kullanacak olduğumuz Film veri tabanını seçerek işlememizi tamamlıyoruz.

İşlemlerimiz sonucunda Models klasörünün altında FilmDbModel.edmx dosyamız oluşmuş ve mapping browser ekranımız aşağıdaki resimde gördüğümüz şekilde oluşturulmuştur. Burada Column Mapping bölümünde veri tabanı kolonlarına karşılık gelen deger/özellikler ekranı oluşturulmuş ve kullanımıza sunulmuştur. Film tablomuza göre oluşturulmuş kolon mappingi değerleri aşağıdaki gibidir;

Id -> Id:Int32
Film_Adi -> Film_Adi:String
Yonetmen -> Yonetmen:String
Cikis_Tarihi -> Cikis_Tarihi:DateTime



Sınıfımızın adı ile veri tabanımızın adının çakışmaması için ismini Filmler olarak değiştiriyoruz. Başka bir zaman veri tabanı üzerinden direk işlem yapmaya kalkıştığımızda vermiş olduğumuz isimlerin çakışmaması için böyle bir değişiklik yaptık.

ASP.NET MVC Controller Oluşturuyoruz...

Projemizi ilk oluşturduğumuzda Controller klasörümüzün içerisindeki HomeController.cs kod dosyamızı silmiştik. Şimdi tekrardan bu sınıfımızı oluşturacağız. Uygulamamızın Solution Explorer ‘da Controllers klasörünün üzerinde Add->Controller... adımlarını izleyerek yeni bir controller sınıfı ekliyoruz.



Ekleyecek olduğumuz controller sınıfına silmiş olduğumuz HomeController adını veriyoruz, Create, Update ve Detail seçeneği seçili olacak şekilde işlemimizi tamamlıyoruz.



Eklediğimiz sınıfın kod içeriği varsayılan olarak aşağıdaki gibi olacaktır.

Controllers\HomeController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;


namespace FilmUygulama.Controllers
{
   public class HomeController : Controller
   {
      //
      // GET: /Home/

      public ActionResult Index()
      {
         return View();
      }

      //
      // GET: /Home/Details/5

      public ActionResult Details(int id)
      {
         return View();
      }

      //
      // GET: /Home/Create

      public ActionResult Create()
      {
         return View();
      }

      //
      // POST: /Home/Create

      [AcceptVerbs(HttpVerbs.Post)]
      public ActionResult Create(FormCollection collection)
      {
         try
         {
            // TODO: Add insert logic here

            return RedirectToAction("Index");
         }
         catch
         {
            return View();
         }
      }

      //
      // GET: /Home/Edit/5

      public ActionResult Edit(int id)
      {
         return View();
      }

      //
      // POST: /Home/Edit/5

      [AcceptVerbs(HttpVerbs.Post)]
      public ActionResult Edit(int id, FormCollection collection)
      {
         try
         {
            // TODO: Add update logic here

            return RedirectToAction("Index");
         }
         catch
         {
            return View();
         }
      }
  }
}

Veri Tabanındaki Kayıtları Nasıl Listeleriz ?

HomeController sınıfında Index() metodu kayıtların listelenmesi için varsayılan metod olarak kabul edilmiştir. Index Controller ‘da ilk olarak çağırılacak metod olarak MVC ‘de karşımıza çıkmaktadır.

Index() metodunu veri tabanındaki Film tablosunda yer alan kayıtları göstermek için kullanacağız. Bu işlem için ilk yapmamız gereken Model katmanımızda map ettiğimiz Film tablosunu index metodunda kullanılacak bir şekilde düzenlemek olacaktır.

İsim alanı olarak FilmUygulama.Models ‘i ekledikten sonra index() metodunun üzerine model entity ‘i kod parçasını ekliyoruz.

private SirketEntities _db = new SirketEntities();

Sonrasında da return Index ‘e _db.FilmlerSet.ToList() anlatımını (expression) ekliyoruz. Düzenlemelerimiz sonucunda Index metodumuzun aşağıdaki şekilde olmuştur.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using FilmUygulama.Models;

namespace FilmUygulama.Controllers
{
    public class HomeController : Controller
    {
       //
       // GET: /Home/
       private SirketEntities _db = new SirketEntities();

       public ActionResult Index()
       {
          return View(_db.FilmlerSet.ToList());
       }
    }
}

Şimdi Index() metodunu kullanan bir View sayfa yapmamız gerekmektedir. Eskiden ve MVC kullanılmayan uygulamalarda hala bu işlemi yeni bir web sayfası oluşturur. Bi masterpage ‘e bağlayıp, sonrasında da veri tabanından çektiğimiz alanları sayfamızda kullandığımız server kontrollerine bağlayarak işlemlerimizi tamamlıyorduk. MVC Framework ile sonucu yine aynı olmasına karşı yapılış yöntemi biraz farklı ve basit. J

Biraz önce düzenlemiş olduğumuz index() metodumuzun üzerine faremiz ile sağ tıklama yapıyoruz.



Sonrasında karşımıza çıkan ekranda View Name ‘i index ve type ‘i de model katmanından alacağını belirterek işlemimizi tamamlıyoruz.



İşlemimiz sonucunda View klasörünün içerisine Home klasörü ve içerisinde index.aspx sayfamız oluşmuştur.

Views\Home\index.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<FilmUygulama.Models.Filmler>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Index
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Index</h2>

<table>
   <tr>
      <th></th>
      <th>
         Id
      </th>
      <th>
         Film_Adi
      </th>
      <th>
         Yonetmen
      </th>
      <th>
         Cikis_Tarihi
      </th>
   </tr>

<% foreach (var item in Model) { %>

   <tr>
      <td>
         <%= Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
         <%= Html.ActionLink("Details", "Details", new { id=item.Id })%>
      </td>
      <td>
         <%= Html.Encode(item.Id) %>
      </td>
      <td>
         <%= Html.Encode(item.Film_Adi) %>
      </td>
      <td>
         <%= Html.Encode(item.Yonetmen) %>
      </td>
      <td>
         <%= Html.Encode(String.Format("{0:g}", item.Cikis_Tarihi)) %>
      </td>
   </tr>

<% } %>

</table>

<p>
   <%= Html.ActionLink("Create New", "Create") %>
</p>

</asp:Content>

Oluşmuş olan sayfamızı incelediğimizde bizim için bir tablo görünümde veriler oluşturulmuş. Sonrasında ise model nesnesinin içerisindeki verilerde foreach döngüsü ile dönülerek bütün kayıtlar bizlere sunulmuştur.



Yeni bir kayıt oluşturuyoruz...

Index metodunda yapmış olduğumuz düzenlemeler ile Film tablosuna elle girmiş olduğumuz verileri sorunsuzca getirdik. Şimdi ise veri tabanına yeni bir kayıt eklemek istersek nasıl yapacağımızı incelemeyeceğiz.

Yeni bir kayıt işlemini parametresiz Create() metodu ile Create() metodunu aşırı yüklenmiş ve server post yolu ile haberleşen Create() metodu ile gerçekleştiriyoruz.

Aşırı yüklenmiş olan Create() metodu içersine form üzerinde kullanıcılar tarafında girilmiş olan değerleri alarak veri tabanına kayıt yapmaktadır.

Create() metodunu düzenleyerek kayıt yapar hale getirelim.

Create metodunu özelleştirme ilk başta kullanıcı tarafından girilmemesi gereken alanları çıkarmakla başlayalım. Bu işlemi yapmanın en basit yolu Bind edilecek olan alanlardan istediklerimizi çıkarmak olacaktır.

public ActionResult Create([Bind(Exclude=”Id”)] Filmler filmlerToCreate)

kod bloğunu kullanmamız durumunda artık Id yeni bir kayıt oluşturma esnasında kullanıcıya değer girmesi için gösterilmeyecektir.

ModelState form üzerinden verileri bind yolu ile iki yönlü kontrolünü yapar. Bizde ilk olarak isteğin ModelState ‘ten gelip gelmediğini kontrol edeceğiz.



Kontrollerimizi tamamladıktan sonra artık yeni bir kayıt işlemini yapabilecek durumu gelmiş bulunuyoruz. Yapmamız gereken, kod bloğumuzda kullanmış olduğumuz _db sınıfının içerisinde yer alan AddToFilmlerSet() metodunu kullanarak parametre olarak form üzerindeki değerleri toplamış olarak filmlerToCreate kolleksiyonunu vermemiz sonrasında da SaveChanges() metodu ile kayıt işlemimizin tamamlandığını belirtmemiz yeterli olacaktır.

Yapmış olduğumuz düzenlemeler sonucunda Create metodlarımız aşağıdaki gibi olmuştur.

//
// GET: /Home/Create

public ActionResult Create()
{
   return View();
}

//
// POST: /Home/Create

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude="Id")] Filmler filmlerToCreate)
{
   if (!ModelState.IsValid)
      return Create();
   try
   {
      _db.AddToFilmlerSet(filmlerToCreate);
      _db.SaveChanges();

       return RedirectToAction("index");
   }
   catch
    { return View(); }
}
Visual Studio yardımı ile basitçe Create web sayfamızı oluşturuyoruz. Yapmamız gerek index sayfasında olduğu gibi metodumuzun üzerinde sağ tıklama ile AddView seçeneğine tıklıyoruz. Sonrasında karşımıza çıkan ekranda içerik kısmında Create ‘i type tarafında da filmleri seçerek işlemimizi tamamlıyoruz.



View\Home\Create.aspx
s<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<FilmUygulama.Models.Filmler>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   Create
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

   <h2>Create</h2>

   <%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>

   <% using (Html.BeginForm()) {%>

   <fieldset>
      <legend>Fields</legend>
      <p>
         <label for="Id">Id:</label>
         <%= Html.TextBox("Id") %>
         <%= Html.ValidationMessage("Id", "*") %>
      </p>
      <p>
         <label for="Film_Adi">Film_Adi:</label>
         <%= Html.TextBox("Film_Adi") %>
         <%= Html.ValidationMessage("Film_Adi", "*") %>
      </p>
      <p>
         <label for="Yonetmen">Yonetmen:</label>
         <%= Html.TextBox("Yonetmen") %>
         <%= Html.ValidationMessage("Yonetmen", "*") %>
      </p>
      <p>
         <label for="Cikis_Tarihi">Cikis_Tarihi:</label>
         <%= Html.TextBox("Cikis_Tarihi") %>
         <%= Html.ValidationMessage("Cikis_Tarihi", "*") %>
     </p>
     <p>
        <input type="submit" value="Create" />
     </p>
   </fieldset>

   <% } %>

   <div>
      <%=Html.ActionLink("Back to List", "Index") %>
   </div>

</asp:Content>



Film tablosunda boş geçilemez olarak tanımladığımız alanlar web sayfamıza da o şekilde aktarılmıştır. Ek olarak ID alanına dikkatinizi çekmek istiyorum. Hem aspx kod tarafında hem de ekran göreceğiniz üzere ID alanı gelmiştir. Fakat hatırlayacağınız üzere biz Create metodunda bu alanın bind edilmemesini istemiştik. Bu ID alanını görünmez kılmaz sadece kullanılmaz kılar. Yani biz ID ‘ye hangi değeri girersek girelim o tabloyu oluştururken tanımladığımız gibi otomatik artan bir sayı olarak değerlerini almaya devam edecektir. Yani ID alanını sayfamızdan çıkarttığımız durumda da işleyişimiz sorunsuz bir biçimde devam edecektir.

Değerlerimizi doğru bir biçimde girip kaydı oluştur dediğimizde sorunsuzca kaydımız gerçekleşecek ve index sayfamızda gözükecektir.

Kayıt düzenleme işlemini yapıyoruz...

Yazımız boyunca kayıtları listeleme ve yeni kayıt ekleme işlemlerini ne kadar kolay bir şekilde yapabildiğimize göz attık. Son olarak Düzenleme (Edit) işlemini nasıl yaptığımıza bakarak bu yazımızı sonlandıracağız.

Diğer işlemlerimizi yaparken Index() ve Create() metodlarını kullanmıştık. Düzenleme işlemi için ise HomeController.cs sınıfının içerisinde yer alan Edit() metodlarını kullanıyor olacağız. Edit ‘te Create ‘te olduğu gibi iki metoddan oluşmaktadır. Birincisi Id ‘den yararlanarak düzenlenecek olan kayıda ilişkin verileri form kontrollerine bind eder. İkincisi ise form kontrollerine bind edilmiş olan veriler üzerinde yapılmış olan değişiklikleri günceller.

İsterseniz bu sefer ilk olarak View klasörümüzün altında yer alacak olan Edit sayfamızı oluşturup ondan sonra metodlarımız içerisindeki gerekli düzenlemeleri yapalım.

Edit sayfamızı oluşturmak için metodumuzun üzerinde faremiz ile sağ tıklama sonrasında AddView seçeneğine tıkladıktan sonra karşımıza gelen ekranda ListContent tarafında Edit ‘i seçerek sayfamızı oluşturuyoruz.



Sayfamız oluşmuş durumda. Şimdi de Edit metodlarında düzenlemelerimizi yapıyoruz.

//
// GET: /Home/Edit/5

public ActionResult Edit(int id)
{
    var filmlerToEdit = (from m in _db.FilmlerSet
            where m.Id == id
            select m).First();
   return View(filmlerToEdit);
}

//
// POST: /Home/Edit/5

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Filmler filmlerToEdit)
{
   if (!ModelState.IsValid)
   return View();
   try
   {
      // TODO: Add update logic here
      var orjinalFilm = (from m in _db.FilmlerSet
               where m.Id == filmlerToEdit.Id
               select m).First();
       _db.ApplyPropertyChanges(orjinalFilm.EntityKey.EntitySetName, filmlerToEdit);
       _db.SaveChanges();

      return RedirectToAction("Index");
    }
    catch
    { return View(); }
}

Post edilmemiş edit metodunda Id ‘den yararlanılarak veriler getirilirken Post edilecek olan edit metodundan ID ile getirilmiş değerlerdeki verilerin güncelleme işlemi yapılmıştır.



Kaydet dediğimizde değişiklik işlemi tamamlanmış olacaktır.

Bir yazımızın sonuna daha geldik. MVC ile nasıl web sitesi oluşturulduğunu, veri tabanında oluşturmuş olduğumuz bir tabloyu Entity Framework ile nasıl kullanabileceğimizi ve bunu nasıl MVC Framework kullanılarak hazırlanmış bir web sitesinde kullanabileceğimizi, oluşturmuş olduğumuz model katmanı üzerinden select, create ve update işlemlerini nasıl yapacağımızı adım adım incelemeye çalıştık.

Diğer MVC yazılarımızda, bu yazımızda değinmiş olduğumuz controller, routing ve diğer bir çok konuyu açıklayarak devam ediyor olacağız.

Herkese mutlu ve başarılı bir gün diliyorum.

Salı, Mart 24, 2009

YazGeliştir Seminerleri @İstanbul - Yıldız Teknik Üniversitesi

Merhabalar,

Benim konuşmacıları arasında olduğum Yazgelistir ekibi 28 Mart Cumartesi günü Yıldız Teknik Üniversitesinde olacağız. Benim anlatacağım konu Windows Presentation Foundation. Etkinlik ile ilgili duyuruyu yazının devamında okuyabilirsiniz. Katılımlarınızı büyük bir merak ve heyacanla bekliyoruz…

Duyuru;

Yazgeliştir, 2009 seminer turuna Yıldız Teknik Üniversitesi'nden devam ediyor. 28 Mart 2009 Cumartesi günü tüm gün sürecek olan, altı konuşmacının yedi ayrı konuyu anlatacağı seminerlerde sizde yerinizi alın!
Etkinlik Tarihi: 28 Mart 2009 Cumartesi

Etkinlik Programı:

09:30-10:15:    Mustafa Acungil - İş zekası nedir?
10:15-10:30:    ARA
10:30-11:15:    Mustafa Acungil - SQL Server 2008 İle Gelen Yeni Veri Tipleri
11:15-11:30:    ARA
11:30-12:15:    Volkan Korkmaz - Dynamics CRM 4.0
12:15-13:00:    YEMEK ARASI
13:00-13:45:    Turhal Temizer - Windows Presentation Foundation
13:45-14:00:    ARA
14:00-14:45:    Burak Batur - Microsoft Office SharePoint Server 2007
14:45-15:00:    ARA
15:00-15:45:    Daron Yöndem - MultiPoint Programlama
15:45-16:00:    ARA
16:00-16:45:    Emre Coşkun - Composite WPF

Etkinlik Yeri :
Yıldız Teknik Üniversitesi Beşiktaş Kampüsü, YTÜ C Blok Konferans Salonu

Pazartesi, Kasım 10, 2008

CLIP - Caption Language Interface Pack

Visual Studio 2008 menülerinin Türkçeleştirilmesi için CLIP aracı Web üzerinden yayınlandı. CLIP, Visual Studio 2008'deki görsel arayüz maddelerinin yerel dildeki çevirilerini bir araç çubuğu yardımcı balonu (tooltip) veya diyalog kutusu içerisinde gösteren bir araç. Kullanıcılar görsel arayüz elemanlarının üzerinden fare ile geçerek çeviriyi anında görebiliyorlar. Ürünün 1.0 versiyonu Visual Studio IDE'sinin çoğu görsel elemanını çeviriyor. Ürün hakkında daha fazla bilgiyi buradan alabilirsiniz. 

CLIP aracının Türkçesini aşağıdaki adresten indirip kurabilirsiniz. Araç kurulduktan sonra Windows'un Sistem Çubuğu'nda (System Tray) yer alacak ve araçla ilgili seçeneklere buradaki ikondan ulaşabileceksiniz.

http://www.microsoft.com/downloads/details.aspx?FamilyID=4e5258d2-52f4-46b8-8b74-da2dbec7c2f7&displaylang=tr

Cumartesi, Ağustos 09, 2008

Sharepoint için Silverlight --> Blueprint

Çalıştığım şirketteki pozisyonum gereği belli bir süredir Sharepoint, WSS, MOSS gibi teknloljileri inceliyorum ve uygulama geliştiriyorum. Bu araştırmalarım esnasında Silverlight ile Sharepoint 'in entegreli olarak çalışabildiğine ve buna da Blueprint dendiğini gördüm.
Silverlight uygulamalarını sharepoint üzerinde çalıştırmak istediğimizde bizden hangi versiyon ile çalışmak istediğimiz hangi kod dosyası ile geliştirme yapmak istediğimiz gibi işlemleri yapmamızı istemektedir.
Kullanmak isteyenler ilk olarak bir Virtual PC indirmelidir. Daha sonra Microsoft tarafında 30 günlük deneme sürümü olarak hazırlanan ve içerisinde MOSS ve WSS kurulu olan Windows Server 2003 'ü indirmeleri gerekmektedir. Daha sonrasında ise yapacağınız uygulamalar geliştirmek olacaktır.
İyi çalışmalar...
Not: Blueprint ile ilgili daha ayrıntılı bilgi için İngilizce olarak yazılmış olan yazıda yer alan linklerden yararlanabilirsiniz...

Pazar, Temmuz 20, 2008

Silverlight 2.0 - DeepZoom Teknolojisi

Windows Presentation Foundation ile yapılmış ilk örnekleri incelerken kütüphaneler için yapılmış uygulamalar ve kullanılan teknikler bizleri oldukça şaşırtmıştı. Kütüphanelerde yer alan kitaplar çok yüksek çözünürlüklerle tarandıktan sonra kitap haline getirilerek kullanıma sunuluyordu. Fakat ufak bir detay dikkatimizi çekmekteydi. Bu da gözükecek olan resimlerin tamamı net değildi. Yalnızca yakınlaştırılan nokta netleşiyor, diğer noktalar ise bulanık kalmaya devam ediyordu. Bu yöntem sayesinde o çok büyük boyutlu resmin tamamının gösterilmesi için gerekli zaman beklenilmesi yerine kullanıcının istediği nokta netleştirilerek daha hızlı işlem yapılması sağlanmaktaydı.

Zaman ilerledikçe bu tür uygulamaları Silverlight ile de yapıldığını gördük. Fakat 1.x sürümü ile yapılan uygulamalarda çok uzun satırlarca JavaScript kodu yazılması gerektiği için geliştiricilerin tercih sıralamasında geride kalıyordu. Silverlight ‘ın 2.0 sürümüne ilişkin çalışmalarda bu güzel özelliğin kullanıcılar ve geliştiriciler tarafında çok beğenildiğinin fakat geliştirme kısmına gelindiğinde zorluklarından ötürü kaçınıldığının farkına varılmıştır. Bu düşünce sonucunda ise ek yazılımlar yardımı ile geliştiricilere yardım edilmesine olanak tanınmak istenmiştir.

Bu yazımızda Silverlight 2.0 ile gelen yeni özelliklerden birisi olan DeepZoom ‘u inceliyor olacağız. DeepZoom teknolojisi internet üzerinde gösterilmesi zor olabilecek çok büyük çözünürlükteki resimleri alıp o anda ekranda görebileceğiniz kadarını netleştirerek gösteriyor, teknik olarak bunu da resimleri parçalara ayırarak ve farklı çözünürlüklerde kaydederek yapıyor, böylelikle bir son kullanıcı rahatlıkla 2-3 GB’lık resimleri bile tek bir ekranda görüntüleyebiliyor. Özellikle HD Fotoğraflar ile birlikte bu teknolojinin daha fazla artacaktır.

DeepZoom fikrinin ortaya atılmasını sağlayan proje SeaDragon projesidir. Bu proje esnasında kullanılan tekniklerin tamamına yakını DeepZoom uygulamasında da kullanılmaktadır. Peki, DeepZoom ‘u nasıl elde edebiliriz. Microsoft ‘un web sayfası yardımı ile
bu linkten
indirilmesi mümkündür. 4.4 mb ‘lik bir kurulum dosyası indikten sonra bilgisayarımıza kurulum yapıyoruz. Kurulumdan sonraki ilk ekranda karşımıza aşağıdaki gibi bir ekran gelmektedir.



Kullanım ekranı Expression Blend ‘e oldukça fazla benzemektedir. Uygulamamızı oluşturmaya yeni bir proje oluştur seçeneğine tıkladıktan sonra karşımıza çıkacak olan ekrana tamam diyerek başlıyoruz.

Uygulamamızı nasıl oluşturacağımıza değinmeden önce DeepZoom ‘un kullandığı mantığı birde görüntüsel olarak incelersek daha mantıklı olacaktır. DeepZoom büyük bir resmin küçük bir parçasını net olarak kullanıcıya sunarken diğer kısımları sistemi yavaşlatmamak için net olarak göstermemektedir.


Resimden de dikkat edeceğiniz üzere büyük boyutlu bir tamamı ama daha küçük bir biçimde gösterilmektedir. Kullanıcı resmi kendisine yaklaştırdıkça odak noktası dışındaki noktalarda netleşerek büyük boyuttaki resmin netliğine kavuşacaktır.

DeepZoom ‘un çalışma mantığı ile ilgili bu ufak bilgiyi de edindikten sonra uygulama geliştirmeye devam edebiliriz. Şimdi yapmamız gereken yakınlaştırıp uzaklaştıracak olduğumuz resimleri uygulamamıza eklemek olacaktır.



Resimleri çalışmamıza ekledikten sonraki görüntü aşağıdaki gibi olacaktır.



Şimdi yapacağımız işlem ise arka plan olarak bir resmi seçtikten sonra onun üzerine diğer resimleri eklemek olacaktır. Bu işlem için Compose menüsünün kullanılması gerekmektedir.



Ekranımızda Layer View yazan bölümde ekranda yer alan resimlerimizin görünüp görünmemesini gibi özelliklerini ayarlayabiliyoruz.

Bunda sonra yapacağımız işlem ise uygulamanın yayınlanabilir duruma getirilmesi olacaktır. Export menüsüne tıkladıktan sonra karşımıza çıkan ekranda gerekli olan özellikler yer almaktadır.



Export butonuna tıkladığımız zaman ise uygulamamız hazır duruma gelmiş olacaktır. Uygulamayı kullanabileceğimiz seçenekler yayınlama işleminin hemen sonrasında bizlere sunulmaktadır.



Web uygulaması ile göster dediğimizde ise karşımıza oldukça iyi bir uygulama çıkacaktır.












Eğer ki Flash animasyon tamamlanmışsa üzerinde sağa tıkladıktan sonra play seçeneğini seçtiğiniz zaman yeniden görüntüleyebilmeniz mümkündür.

Uygulamamızın çalışması tam istediğimiz gibi görünüyor. Ama kafamıza takılan birkaç soru var. “Uygulamanın çalışmasını sağlayan dosyanın içerisinde neler var?” , ”Hangi kodlar arka planda oluşmuş?” Bu soruların cevapları için ilk olarak uygulanın oluşturulduğu klasöre gitmemiz gerekmektedir. DeepZoom uygulamalarını
C:\Users\Turhal\Documents\Expression\Deep Zoom Composer Projects yolundaki klâsöre oluşturmaktadır. Biz uygulamamızı bulabilmek için bu dizin içerisinden kendi projemizi bularak sonrasında
source images isimli klasörün içerisine bakarak oluşturulan proje dosyalarını ve resimleri bulabilmemiz mümkündür.



Eğer ki uygulamamızın kod tarafında bir değişiklik yapmak istersek DeepZoomProject klasörünü kullanabilir. Web tarafında kullanmamız gereken dosyalar için ise
DeepZoomProjectWeb klasörü isteklerimizi karşılamaya yetecektir.

Kod tarafında nelerin oluşturulduğuna göz atalım şimdide. İlk olarak projemizde resimleri görüntüleyebildiğimiz
Page.XAML dosyasının içerisindeki kodlara göz atıyoruz.

Açtığımız anda dikkatimizi çeken şey Silverlight 2.0 ile gelen MultiScaleImage nesnesinin kullanıldığına ve çağırılan resimlerin bu nesne ile oluşturulan alanın içerisinde gözükmesi sağlandığını görürüz.


Uygulamamızda gösterilen ekranın kod tarafında oluşturulan C# kodlarına göz atarsak…

C#


using System;
using System.Collections.Generic;
using
System.Linq;
using System.Net;
using System.Windows;
using
System.Windows.Controls;
using System.Windows.Documents;
using
System.Windows.Input;
using System.Windows.Media;
using
System.Windows.Media.Animation;
using System.Windows.Shapes;


namespace DeepZoomProject
{
    public partial class Page : UserControl

   
{

        Point lastMousePos = new Point();

        double _zoom = 1;
        bool
mouseButtonPressed = false;
        bool mouseIsDragging = false;
        Point
dragOffset;
        Point currentPosition;

        public double ZoomFactor
        {

           
get { return _zoom; }
            set { _zoom = value; }
        }

        public Page()

       
{
            InitializeComponent();

            //
            // Blend yardımcı ile XAML
özellikler oluşturuluyor.
            //
            this.msi.Source = new
DeepZoomImageTileSource(new Uri("GeneratedImages/dzc_output.xml", UriKind.Relative));


            //
            // MultiScaleImage yükleniyor
            //
            this.msi.Loaded += new
RoutedEventHandler(msi_Loaded);

            //
            // MultiScaleImage yüklendikten
sonra diğer bütün resimler yüklenmeye başlıyor
            //
            this.msi.ImageOpenSucceeded
+= new RoutedEventHandler(msi_ImageOpenSucceeded);

            //
            // Klavyeden
basılan tuşları algılıyor.
            //
            this.MouseMove += delegate(object sender,
MouseEventArgs e)
            {
                if (mouseButtonPressed)
                {
                    mouseIsDragging =
true;
                }
                this.lastMousePos = e.GetPosition(this.msi);
            };

            this.MouseLeftButtonDown
+= delegate(object sender, MouseButtonEventArgs e)
            {

               
mouseButtonPressed = true;
                mouseIsDragging = false;
                dragOffset = e.GetPosition(this);

               
currentPosition = msi.ViewportOrigin;
            };

            this.msi.MouseLeave +=
delegate(object sender, MouseEventArgs e)
            {
                mouseIsDragging = false;

           
};

            this.MouseLeftButtonUp += delegate(object sender,
MouseButtonEventArgs e)
            {
                mouseButtonPressed = false;
                if (mouseIsDragging
== false)
                {
                    bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift)
== ModifierKeys.Shift;

                    ZoomFactor = 2.0;
                    if (shiftDown) ZoomFactor
= 0.5;
                    Zoom(ZoomFactor, this.lastMousePos);
                }
                mouseIsDragging =
false;
            };

            this.MouseMove += delegate(object sender, MouseEventArgs
e)
            {
                if (mouseIsDragging)
                {
                    Point newOrigin = new Point();

                   
newOrigin.X = currentPosition.X - (((e.GetPosition(msi).X - dragOffset.X) /
msi.ActualWidth) * msi.ViewportWidth);
                    newOrigin.Y = currentPosition.Y -
(((e.GetPosition(msi).Y - dragOffset.Y) / msi.ActualHeight) * msi.ViewportWidth);

                   
msi.ViewportOrigin = newOrigin;
                }
            };

            new MouseWheelHelper(this).Moved
+= delegate(object sender, MouseWheelEventArgs e)
            {
                e.Handled = true;

               
if (e.Delta > 0)
                    ZoomFactor = 1.2;
                else
                    ZoomFactor = .80;


                   
Zoom(ZoomFactor, this.lastMousePos);
            };
        }

        void msi_ImageOpenSucceeded(object
sender, RoutedEventArgs e)
        {
        }

        void msi_Loaded(object sender,
RoutedEventArgs e)
        {
            Zoom(.5, new Point(this.ActualWidth / 2, this.ActualHeight
/ 2));
        }

        public void Zoom(double zoom, Point pointToZoom)
        {

           
Point logicalPoint = this.msi.ElementToLogicalPoint(pointToZoom);
            this.msi.ZoomAboutLogicalPoint(zoom,
logicalPoint.X, logicalPoint.Y);
        }


    }
}



Şeklinde oluşturulduğunu görürüz. Yukarıdaki kod bloğunda bizleri dikkatini çeken bölüm farenin hareketi sonucunda görüntünün nasıl hareket ettiği bloktur
C#



this.MouseMove += delegate(object sender, MouseEventArgs e)
{
   
if (mouseIsDragging)
        {
           
Point newOrigin = new Point();
           
newOrigin.X = currentPosition.X - (((e.GetPosition(msi).X - dragOffset.X) /
msi.ActualWidth) * msi.ViewportWidth);
           
newOrigin.Y = currentPosition.Y - (((e.GetPosition(msi).Y - dragOffset.Y) /
msi.ActualHeight) * msi.ViewportWidth);
           
msi.ViewportOrigin = newOrigin;
       
}
};


Yukarıdaki kod bloğunda ekran üzerindeki son pozisyonu alındıktan sonra fare ile sürüklenen, yakınlaştırılan değerleri alınarak yeni değerlere atanıyor. Sonrasında ise ekran üzerindeki yeni yeri belirlenebiliyor.

Projemizde oluşturulan kod bloklarından biride Farenin sürükleme topu ile yapılmış işlemlerin nasıl algılanacağına ait sınıftır.

C#


using System;
using System.Net;
using System.Windows;

using System.Windows.Controls;
using System.Windows.Documents;
using
System.Windows.Ink;
using System.Windows.Input;
using
System.Windows.Media;
using System.Windows.Media.Animation;
using
System.Windows.Shapes;
using System.Windows.Browser;

namespace
DeepZoomProject
{
    // Courtesy of Pete Blois
    public class
MouseWheelEventArgs : EventArgs
    {
        private double delta;
        private
bool handled = false;

        public MouseWheelEventArgs(double delta)
        {

           
this.delta = delta;
        }

        public double Delta
        {
            get { return
this.delta; }
        }

        // Use handled to prevent the default browser
behavior!
        public bool Handled
        {
            get { return this.handled; }
            set
{ this.handled = value; }
        }
    }

    public class MouseWheelHelper

   
{

        public event EventHandler<MouseWheelEventArgs> Moved;
        private
static Worker worker;
        private bool isMouseOver = false;

        public
MouseWheelHelper(FrameworkElement element)
        {

            if (MouseWheelHelper.worker
== null)
            MouseWheelHelper.worker = new Worker();
            MouseWheelHelper.worker.Moved
+= this.HandleMouseWheel;
            element.MouseEnter += this.HandleMouseEnter;

           
element.MouseLeave += this.HandleMouseLeave;
            element.MouseMove += this.HandleMouseMove;

       
}

        private void HandleMouseWheel(object sender, MouseWheelEventArgs
args)
        {
            if (this.isMouseOver)
            this.Moved(this, args);
        }


       
private void HandleMouseEnter(object sender, EventArgs e)
        {
            this.isMouseOver
= true;
        }

        private void HandleMouseLeave(object sender, EventArgs
e)
        {
            this.isMouseOver = false;
        }

        private void
HandleMouseMove(object sender, EventArgs e)
        {
            this.isMouseOver = true;

       
}

        private class Worker
        {
            public event EventHandler<MouseWheelEventArgs>
Moved;
           

            public Worker()
            {

                if (HtmlPage.IsEnabled)
                {

                   
HtmlPage.Window.AttachEvent("DOMMouseScroll", this.HandleMouseWheel);

                   
HtmlPage.Window.AttachEvent("onmousewheel", this.HandleMouseWheel);

                   
HtmlPage.Document.AttachEvent("onmousewheel", this.HandleMouseWheel);
                }


            }

            private void HandleMouseWheel(object sender, HtmlEventArgs args)

           
{
                double delta = 0;

                ScriptObject eventObj = args.EventObject;


                if (eventObj.GetProperty("wheelDelta") != null)
                {
                    delta = ((double)eventObj.GetProperty("wheelDelta"))
/ 120;

                    if (HtmlPage.Window.GetProperty("opera") != null)
                    delta
= -delta;
                }
                else if (eventObj.GetProperty("detail") != null)
                {

                   
delta = -((double)eventObj.GetProperty("detail")) / 3;

                    if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh")
!= -1)
                    delta = delta * 3;
                }

                if (delta != 0 && this.Moved !=
null)
                {
                    MouseWheelEventArgs wheelArgs = new MouseWheelEventArgs(delta);

                   
this.Moved(this, wheelArgs);

                    if (wheelArgs.Handled)
                    args.PreventDefault();

               
}
            }
        }
    }
}

Bu sınıfta ise farenin kaydırma topu ile yapılan hareketleri algılayarak uygulamamıza ait sınıfın içerisinde oluşturulan yakınlaştırma ve uzaklaştırma ile ilgili kod bloğunda kullanılmaktadır.

Sonuç olarak Silverlight 2.0 ‘ın yeni özelliklerinden olan DeepZoom ‘u incelemeye çalıştık. Çok büyük boyutlardaki resimleri web uygulamalarında tamamını göstermek yerine yaklaştırdıkça belirli alanlarını göstererek performansı nasıl arttırabileceğimize değinmeye çalıştık.

Bir sonraki Silverlight makalemizde ise MultiScaleImage kontrolü otomatik olarak değilde kendimiz kullanarak uygulama geliştirmek istersek nasıl yapabileceğimize değinmeye çalışacağız.

Umarım yararlı olmuştur.
turhal.temizer@csharpnedir.com

Cumartesi, Temmuz 19, 2008

Silverlight 2.0 - Kontrollerin Özelleştirilmesi, VSM ve Yenilikleri

Microsoft, Silverlight ‘ı gün geçtikçe benzersiz bir yapı haline dönüştürüyor. Günler geçtikçe kontroller, aspx desteği derken Asp.Net ‘te pek alışık olmadığımız bir durum olan kontrollerin özelleştirmesi özelliği Beta2 sürümü ile eklenmiş olduğunu gözlemleyebiliyoruz. Peki, Silverlight bugüne gelene kadar ne tür gelişmeler gösterdi.

Alpha1 sürümünde JavaScript ve HTML ile interaktif web uygulamaları geliştirebiliyorduk.
Alpha2 sürümü ile yukarıdakilere ek olarak XAML ‘de eklendi.
Beta1 sürümünde WPF ‘te kullanılan kütüphane kısmen geçirilmeye başlandı.
Silverlight 1.0 sürümünde yukarıda bahsettiğimiz deneme işlemleri uygulanabilir düzeye getirildi.
Silverlight 1.1 sürümünde buton gibi temel kontroller Silverlight bünyesine eklendi.
Silverlight 2.0 Beta1 ile web servis işlemlerinden veri bağlamaya kadar bir çok özellik eklendi fakat en çok dikkat çekeni kullanılabilir Silverlight kontrolü sayısı arttırıldı.
Silverlight 2.0 Beta2 sürümü ile ise Beta1 sürümünden eklenen bir çok özellik geliştirildi. Asya dilleri eklendi. En çok göze çarpan özelliği ise Expression Blend ürünü ile Silverlight kontrollerinin düzenlenebilmesi olmuştur.

Silverlight ‘ın günümüze kadar geçirmiş olduğu gelişim temel olarak bu şekildedir. Tabii saydığımız özelliklere ek olarak video streaming özelliği en popüler olanıdır. Videoların gösterilme süreleri o kadar iyileşti ki web üzerinden canlı yayınlar yapılabildi ve HD videoların fragmanları sorunsuz bir biçimde kullanıcılara izletilebildi.

Eski sürümlerde neler yapabildiğimiz ile ilgili ayrıntılı bilgilere ulaşmak isterseniz daha önceden yayınlanmış olan makaleleri okumanızı öneririz.

Silverlight 2 Beta2 ile uygulama geliştirebilmeniz için http://www.microsoft.com/downloads/results.aspx?pocId=&freetext=silverlight%202%20beta2&DisplayLang=en adresinden gerekli bileşenleri bilgisayarınıza indirdikten sonra kurarak kullanmaya başlayabilirsiniz. Ayrıca yazımızda kontrollerin özelleştirilmesi işlemleri Expression Blend 2.5 June Preview ile yapacağız. Bu programı kullanabilmeniz için gerekli link ise http://www.microsoft.com/downloads/results.aspx?pocId=&freetext=expression%20blend%202.5%20june%20preview&DisplayLang=en adresinden yararlanabilirsiniz. Gerekli programları edindiğimize göre artık yazımızın içeriğini incelemeye başlayabiliriz.

KULLANICI KONTROLLERİ
Silverlight ilk sürümlerinde WPF ‘e yetişmesi uzun yıllar alacağı konusunda söylentiler varken şu anda WPF ‘te bile olmayan kontrolleri bünyesinde barındırmaktadır. Özellikle DataGrid kontrolü WPF ‘te olmadığı halde Silverlight 2.0 Beta2 ‘de yerini almıştır.



Bu ve diğer kontrollere ek olarak TabPanel kontrolü de Beta2 sürümü ile bizlerin kullanımına sunulmuştur. Şu an itibari ile Silverlight2 Beta2 sürümünde 30 ‘ün üzerinde kontrol bulunmaktadır. Geliştiricileri tarafından yapılan açıklamada ise 2.0 sürümü tamamlandığı zaman 100 ‘ün üzerinde kontrolün bizlere sunulacağı belirtilmiştir.

Kontrollerin Özelleştirilmesi
WPF ve Silverlight ile son kullanıcılar için hazırlanmış olan kontroller Expression Blend yardımı ile özelleştirilebilmektedir. Özelleştirdiğimiz kontrolleri daha sonrasında geliştirmiş olduğumuz uygulamada XAML kod tarafına ekleyerek kullanılabilir düzeye getirilebilmesi mümkündür.

Şimdi Expression Blend yardımı ile kontrolleri nasıl özelleştirebileceğimize göz atalım. Bu işlemi yaparken ilk olarak slider kontrolünden yararlanacağız.

İlk olarak Expression Blend 2.5 June Preview ’den Silverlight 2 projesi oluşturuyoruz. Sonrasında ise uygulama ekranımıza bir tane slider kontrolü ekleyerek işlemlerimize başlıyoruz.



Slider kontrollerini ekledikten sonra şimdi düzenleme işlemini gözlemleyeceğiz. İlk olarak yapmamız gereken kontrolün üzerinde fare ile sağa tıkladıktan sonra çıkan menüden Edit Control Part ‘ı seçeceğiz. Sonrasında çıkan seçenekten Edit a Copy seçeneğine tıklayarak işlemimizi yapmaya devam edeceğiz.



Bu seçeneği seçtiğimizde karşımıza aşağıdaki gibi ekran gelecektir.



Karşımıza çıkan ekranda Name(Key) yazan bölüme istediğimiz ismi verdikten sonra tamam diyerek slider kontrolünü özelleştirebilmemiz mümkündür. Bu verdiğimiz isim app.xaml ‘in içerisinde tutulur ve daha sonradan yapacak olduğumuz işlemleri bu isim altında tutar ve kullanacağımız zaman arka planda bu name ‘i kullanacaktır.

Kontrolü özelleştirebilmemiz için sol tarafta yer alan menüde Template yazan bölümden yararlanacağız. Bu tasarı bölümü bizlere hazırlanan kontrolün hangi nesnelerin toplanması sonucunda oluşturulduğunu göstermektedir. Tasarı bölümünde yer alan ilk dörtgen bölümünde çizginin kalınlığı uzunluğu ve kaydırma butonunun yapısı ile ilgili özellikler tutulmaktadır. Diğerinden ise dikey özellikler yer almaktadır.



Temel olarak bir değişiklik yapmak gerekirse HorizontalThumb ‘ı seçerek uygulamamın çalışma ekranında kaydırma çubuğunun kalınlığını değiştiriyoruz. Sonucunda ise ekranımızda oluşan görüntü aşağıdaki gibi olur.



Gördüğünüz gibi oldukça kolay bir biçimde kontrolleri özelleştirebilmemiz mümkündür. Bu yaptığımız işlemleri uygulayarak diğer bütün kontrolleri de özelleştirebilmemiz mümkündür.

Visual State Manager (VSM) Yapısı
Silverlight ve WPF ‘te hazırlamış olduğumuz kontrollere standart kontrollerden farklı olması için özel işlemler uygulamak isteriz. Örneğin, fare ile kontrolün üzerinde gelindiğinde tıklandığında gibi işlemler sonucunda farklılıkların olmasını isteyebiliriz. Gerçekleştirebilmek için ise yapmamız gereken XAML kod tarafında oldukça fazla kod oluşturan animasyon işlemlerini kullanırız. Arka planda oluşturulan fazla satır kodlar ise kontrol kullanılacağı sırada çağırılacağı için web uygulamalarında yani Silverlight uygulamalarında yavaş çalışmasına sebep olabilir. Web uygulamalarında yaşanabilecek sorunları engellemek için farklı bir çözüm üretilmesi gerekiyordu ve bunun için Visual State Manager (VSM) hazırlanılmış ve biz geliştiricilere sunulmuştur.

VSM, standart olarak hazırlanmış olan kontrolleri özelleştirme işlemimiz ile birlikte fare ile ilgili standart özellikleri de yapılandırabilmemize olanak tanımaktadır. Bizlere kazandırdığı en büyük avantaj ise daha önceden hazırlanmış olan bir animasyon işleminin yeniden düzenlenebilmesi oldukça uğraştırırken VSM kullanarak hazırlanmış olanlar dinamik olarak düzenlenebilmesi mümkündür.

Şimdi VSM ‘i örnek üzerinden incelemeye çalışalım.

Expression Blend ile Silverlight 2 uygulaması açtıktan sonra çalışma ekranımıza bir adet buton sürükleyip bırakıyoruz.



Eklemiş olduğumuz butonun üzerine sağ tıklama yaparak karşımıza çıkan menüden Edit Control Part ‘ı seçiyoruz. Karşımıza çıkan menüden Edit a Copy ‘ı seçerek işlemimizi yapmaya devam ediyoruz.



Edit a Copy seçeneğini tıkladığımız zaman bize aşağıdaki gibi bir ekran çıkmaktadır.



Kontrollerin özelleştirilmesi konusunda da değindiğimiz gibi vermiş olduğumuz name app.xaml içerisinde tutulacak ve kontrol üzerinde yapacak olduğumuz işlemlerin kullanılması için gerekli olan name çağırılması işleminin yapılmasını sağlıyoruz.

Bu işlem sonrasında asıl konumuz olan VSM için gerekli olan state menüsü sol bölümde karşımıza gelmektedir.



State bölümünde Base seçili iken buton kontrolümüzün arka plan ve kenar renklerini değiştireceğiz. Bunun için Template bölümünde Background ve BackgroundGradient özelliklerini değiştireceğiz.



Yaptığımız değişiklik sonucunda butonumuz aşağıdaki gibi olmuştur.



Fare üzerinde gibi özellikleri değiştirmek istediğimizde ise State bölümünde MouseOver seçeneğine ait özelliği değiştirdiğinizde işlemimizi gerçekleştirmiş oluruz.



Temel olarak VSM tasarımcılar ile web geliştiriciler arasındaki uyumu arttıracak ve hazırlanan tasarımların tam anlamında kullanılabilmesine olanak tanıyacak bir özelliktir.

Textbox
Textbox kontrolünde ve genel olarak yazı yazılabilecek bütün kontroller için IME3 adı verilen Asya ve diğer farklı yazım türü olan karakterler eklenmiştir.



Animasyon ve Grafik Sistemi
Silverlight ile hazırlanmış olan animasyon uygulamaları web tarayıcılarda gösterildiğinde çalıştırılan bilgisayarın grafik sisteminde zorlamaya sebep olmaktaydı. Bunun sebebi ise Silverlight, WPF tabanlı olduğu için animasyon uygulamaları çalıştırırken grafik kartının sürücüsünü kullanmak istemektedir. Fakat bu bir web uygulaması için performans yavaşlatıcı bir durumdur. Grafik kartını zorlama oranı beta2 sürümü ile iyileştirilmiş. Tam sürümünde ise zorlama oranının en minimum düzeye getirileceği Silverlight geliştiricileri tarafından açıklanmıştır.

WPF ile uyumu
Silverlight ‘ın gelişimi WPF ‘e oranla daha hızlı olduğu için şu anda aralarında ki uyum azalmış giib gözüküyor. .Net Fw 3.5 Sp1 çıktıktan sonra ise Silverlight ‘ta yapılan değişikler WPF ile uyumlu hala getirilerek XAML kod tarafında yazılan uygulamaların iki platformda da belirli oranda çalışması sağlanacak.

Web Servis
Silverlight ‘ta daha önce SOAP ile web servisi kullanılması mümkündü. Fakat Beta2 sürümü ile WCF servislerinin kullanımı mümkün hal almıştır.

Veri (DATA)

Data Grid
Beta2 sürümünde eklenen bu kontrol de sayfanın boyutuna göre otomatik şekillendirilme, sütunlarda yer alan sonuçların sıralanabilmesi gibi özellikler mümkün kılınmıştır.

NOT: WPF ‘te şu an itibari ile DataGrid kontrolü bulunmamaktadır. .Net Framework 3.5 Sp1 ile ekleneceği düşünülmektedir.

Data Binding
Hataların, zengin içerikli yazıların bağlanabilmesi gibi özellikleri bünyesinde barındırmaktadır.

Silverlight ‘ın gelişimi

Silverlight gün geçtikçe yalnızca animasyon yapabildiğimiz ve video yayınlayabildiğimiz bir yapı olmaktan çıkarak son kullanıcılar için oldukça zevkli uygulamalar geliştirilebilecek, Asp.Net ‘te yapabileceğimiz bir çok işlemi yapabileceğimiz bir yapı olma yolunda ilerlemektedir. Silverlight 2.0 sürümü tamamlandığı zaman web uygulamalarında birçok yazılımcı Asp.Net yerine Silverlight ‘ı deneyecektir. Çünkü kullanıcılara sunduğu zevk ve kolaylık Asp.Net ‘e göre daha fazla olacaktır.

Sonuç olarak yazımızda nelere değindiğimizi hatırlamak gerekirse, Silverlight ‘ın bugüne kadar geçirdiği değişime değindikten sonra kontrollerin özelleştirilmesine, VSM ‘e , Silverlight 2.0 Beta2 ‘de genel özellikler yönünde ne tür değişiklikler yapıldığını ve son olarak da Silverlight ‘ın geleceğe dair gelişiminde ne tür gelişmeler yaşanabileceğine değinmeye çalıştık.

Umarım yararlı olmuştur.

Turhal TEMİZER

Kaynaklar
Silverlight.Net