Oca 01

Kullanım noktasında çok doğru konumlandırılması gereken ürünlerden biri de Expression Studio içerisindeki Expression Media. Eğer ürünle ilgili bilginiz yoksa bilgisayarınıza yükledikten sonra "Ne yapılır ki bununla?" diyip hemen kullanmaktan vaz geçebilirsiniz. Expression Media'nın amacı sizin tüm media dosyalarını yönetmek. Bu noktada ister evinizdeki MP3 arşivinizi ister ofisinizde projelerinize ait dokümanları yönetebilirsiniz. Tabi Word dokümanlarından bahsetmiyoruz, söz konusu olan Media dokümanları, yani videolar, sesler, görsel içerik sunan fotoğraflar vs. Tüm bu çerçevede belki de Microsoft'tan beklemeyeceğimiz bir şekilde QuickTime ve Photoshop dosyalarına destek verilmiş.

Neler yapabiliyoruz?

En önemlisi dosyalarınızı kategorilere ayırabiliyorsunuz, META Tagları ile kategorileme yapabileceğiniz gibi direk fotoğraf makinelerden alınan EXIF bilgilerini kullanma şansınız da var. Tüm bunları yaparken isterseniz tamamen offline çalışabiliyorsunuz. Expression Media içerisinde herhangi bir katalog dosyasına eklediğiniz içeriğin bir harici diskte yer aldığını düşünelim. Harici diskini çıkarsanız da dosyanız üzerinde çoğu işlemi gerçekleştirebiliyorsunuz. Tüm bu işlemler harici disk tekrar takıldığında orijinal dosya üzerinde gerçekleştiriliyor.


Fotoğraflarınızı toplu olarak isimlendirebilir, renk düzenlemeleri yapabilir, HTML kataloglar yaratabilir, XML EXIF bilgileri çıktısı alabilir hatta Expression Media'nın belirli bir klasörü izleyerek yeni eklenen dosyalardan sizi haberdar etmesini de sağlayabilirsiniz. Özellikle fotoğrafçılar için LightTable özelliği de çok değerli olacaktır.

Peki nerden çıktı Expression Media?

Özellikle Mac kullanıcılarının yakından tanıyacağı iMedia View yazılımı Microsoft tarafından satın alındı ve Expression serisine eklendi. Tam olarak bu nedenle Expression Studio içerisinde Mac sürümü olan tek araç Expression Media.

Rakipler ne durumda?

Aynı dalda başka yazılımlar düşündüğümüzde aklımıza ancak Adobe'a ait Lightroom veya Bridge geliyor. Maalesef hiçbiri Expression Media'nın kolay kullanımlı arayüzüne rakip bile olamaz. Belki daha sıkı bir rakip olarak Extensis Portfolio'yu görebiliriz, özellikle sunucu taraflı yazılım desteği ile katalogların paylaşımını da sağlayan yazılım bu noktada Expression Media'nın bir adım önünde.

Sonuç

Kurumsal alanda eğer hali hazırda başka bir ürün kullanmıyorsanız Expression Media doğru seçim olacaktır. Özellikle WPF ve Silverlight programlama ve tasarım yolunda ilerleyen kurumların zaten Expression Studio üzerinden ilerleyeceğini düşünürsek entegrasyon açısından Expression Media çok daha başarılı bir seçim olacaktır. Ama zaten "Bizim bu işleri hallettiğimiz bir yazılımımız var" diyorsanız Expression Media'nın çok büyük yenilikler getirmediğini de kabul etmek lazım.

Expression Studio Savaşları sersindeki önceki yazılarıma aşağıdan ulaşabilirsiniz.

Expression Web ve rakipler
Expression Design ve rakipler

Kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

Expression Web Microsoft'un Office paketi dahilinde yer alan Frontpage ürünün yeni nesil temsilcisi olarak Expression Studio içerisinde yerini alan bir ürün. Frontpage günlerinden bugüne geldiğimizde Expression Web içerisindeki XHTML, XSLT, CSS ve XML desteğinin Intellisense ile beraber gelmesi gerçekten sevindirici. Özellikle yazılımın ASP.NET sayfalarına destek vermesi ve neredeyse tüm ASP.NET sunucu kontrollerinin tasarım aşamasında gerçek görüntüleri ile kullanılabiliyor olması muhteşem. Expression Web içerisinde yaratılan herhangi bir ASP.NET sayfası tasarımcıya ASP.NET Development Server üzerinden çalıştırılarak gösterildiği için tasarımcının bilgisayarında IIS yüklü olması da gerekmiyor.

Tüm bu güzelliklerin yanında maalesef artık Expression Web'e Frontpage gibi bir "giriş seviyesi tasarım aracı" olarak bakmamız mümkün değil. Hatta çoğu giriş seviyesi kullanıcı programın kullanımını zor bile bulacaktır. Diğer yandan hali hazırda rakipler arasından Adobe'un Dreamweaver yazılımını kullanan tasarımcıların ise Expression Web'e geçişleri çok kolay olacaktır. Her iki programın da arayüzleri birbirine çok benziyor. Bir karşılaştırma noktasında Expression Web'in avantajı Visual Studio ile entegrasyon sağlayabilmesi, ayrıca CSS desteği noktasında da sadece bir CSS yönetim paneli değil otomatik entegrasyon sağlaması da güzel bir özellik. Ek olarak direk ASP.NET DataSource kontrolleri ile harici veri kaynaklarına erişebiliyor olmak tasarımcılar için sitenin son hali üzerinde çalışabilmek adına hayati önem arz edecektir.

Expression Web arayüzü.
Expression Web arayüzü.

Benim kişisel olarak Expression Web'de sevdiğim en önemli nokta hızlı açılıyor olması. Takriben Adobe Dreamweaver'a kıyasla 4 kat daha hızlı açılıyor. Bu durum özellikle çok sayıda proje üzerinde çalışırken çok önemli. Herhangi bir dosyayı hemen açarak üzerinde ufak bir değişiklik yapıp kaydetmek gerekebiliyor. Yavaş açılan yazılımlar nedeniyle bazen Notepad kullandığımı bile bilirim. Sırf bu nedenle eskiden de bilgisayarımda FrontPage'i yüklü tutardım, çünkü o da hızlı açılırdı. Aynı özellik Expression Web'de de devam ediyor ve Frontpage'in üzerine gelen bir sürü muhteşem yeni özellik ile bu hıza Expression Web'in rahatlığını da ekleyince benim favori editörüm haline geldiğini söyleyebilirim.

Yukarıda Expression Web'in güzel özelliklerinden bahsederken otomatik CSS yaratabilmesine de değinmiştim. Ama maalesef ben bu özelliği pek de sevmiyorum, genelde otomatik şeylere karşı biraz alerjim vardır :) Ben elle kendi bildiğim gibi yapmayı tercih ederim. Eğer siz de benim gibi düşünüyorsanız Expression Web içerisinde Tools / Page Editor Options / CSS bölümüne giderek otomatik CSS yaratılmasına dair işlevleri kapatabilirsiniz. Expression Web'in CSS Intellisense ve CSS yönetim panelleri çalışmaya devam edecektir fakat otomatik CSS sınıfları artık yaratılmayacaktır.

Expression Studio Savaşları sersindeki bir önceki yazıma aşağıdan ulaşabilirsiniz.

Expression Design ve rakipler

Kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

Expression Studio ailesindeki ürünlerle ilgili "özel" alakamı blogumu takip eden herkes farkındadır :) Bu ilgi ve alaka çerçevesinde aslında sürekli ürünlerle ilgili "Muhteşem" "Süper" demek yerine bir de kelleyi koltuğa alıp ufak bir geziye çıkmaya ve "Neden Expression?" sorusuna bir cevap ararken rakiplerle karşılaştırmalar yapmaya karar verdim. Bugünkü gönüllümüz "Expression Design".

Expression Design kutusu.Genel Bakış

Expression Design'ın geçmişine baktığımızda Microsoft tarafından satın alınmış bir şirket görüyoruz. Creature House ve Fractal Design Corporation tarafından geliştirilen Creature House Expression ürünü özellikle "Skeletal Strokes" olarak adlandırılan özel bir teknikle çizim yapmasıyla dikkati çekiyordu. İlk başlarda Acrylic kod adı ile geliştirilen Expression Graphic Designer sonrasında Expression Designer olarak adlandırıldı. MIX'07'de RTM sürümü tanıtılan ürünün arayüzü tamamen WPF teknolojisi kullanılarak hazırlandı.

Çetin Savaşlar

Expression Design yokken neler kullanıyorduk? Bu bir soru olmakla beraber aslında soru kendi içinde artık söz konusu cevaptaki yazılımları kullanmadığımızı öngörüyor. Ama maalesef her şeyi Expression Design ile yapmamız mümkün değil. Genel hatları ile baktığımızda Adobe'a ait Illustrator ve Fireworks içerisindeki ana araçların çoğu Expression Design içerisinde de var. Bunlara ek olarak özellikle program arayüzünün siyah bir WPF katmanı üzerine yerleştirilmiş olması tasarım çalışmalarındaki renklerin çok daha net gözükebilmesini sağlıyor. Fakat eksikler de saymakla bitmiyor.

İlk olarak Expression Design içerisinde şu an herhangi bir Plug-In desteği yok. Adobe dünyasından tasarımcıların alışkın olduğu üçüncü parti Plug-In'lerin satın alınarak kullanılması noktasında Expression Design tarafında herhangi bir şansınız yok. Maalesef bu çok ciddi bir eksik.

Program aslında Web ortamı için vektörel çizimler sağlasa da (Silverlight aracılığı ile) maalesef herhangi bir web optimizasyon aracı içermiyor. O nedenle hala imajlarınızı optimize ederken Adobe ürünlerine bağımlı kalmak zorundasınız. Özellikle Photoshop içerisindeki Slice araçları benim favorilerimdendi. Aslında tüm özellikler Expression Design'ın betalarında vardı fakat sonradan kaldırıldı. Umarım bir sonraki sürümde tekrar karşımıza çıkarlar. Son olarak Bitmap resim düzenleme konusunda da Expression Design hem içerdiği araçlar açısından hem de kullanım kolaylığı açısından zayıf düşüyor.

Expression Design çalışma ortamı.
Expression Design çalışma ortamı.

Neden Expression Design kullanalım?

Tüm yukarıdaki eksiklere rağmen neden? İlk olarak vektörel bir çizim aracı klasmanında aslında Expression Design neredeyse tüm ihtiyaçlarımızı giderebilecek özelliklere sahip. Unutmamamız gereken bir nokta var ki o da şu an için Expression Design'ın esas amacının Expression Blend'e vektörel XAML çizimleri sağlamak olduğu. Böylece hem WPF hem de Silverlight plaftormunda XAML vektörel içerikler kullanılabiliyor. Expression Design haricinde vektörel çizim yazılımları için de yavaş yavaş XAML Export Plug-In'leri üretilmeye başlandı fakat hali hazırda hiçbiri Expression Design'ın başarısına sahip değil. Peki bu XAML çok mu önemli? Kesinlikle. Eğer WPF ile zengin kullanıcı arayüzleri ve animasyonlar içeren bir windows uygulaması hazırlamak istiyorsanız XAML vektörel çizimler kullanmak zorundasınız. Aynı durum Silverlight için de geçerli.

Bu yazılarımı bir yazı dizisi şeklinde diğer Expression ürün ailesindeki programlar için de yazmayı düşünüyorum. Bir sonrakinde görüşmek üzere ;)

Tags:
Oca 01

Silverlight Streaming Servisleri ile ilgili daha önceki yazılarımda detaylardan bahsetmiştim. Bugün ise size Silverlight Streaming Servisleri ile video yayınını daha da kolaylaştıran bir Plug-In duyuracağım.

Silverlight Streaming Publishing Plug-In for Expression Encoder

Yukarıdaki adresten indirebileceğiniz Expression Encoder eklentisi ile artık direk Expression Encoder kullanarak yarattığınız Silverlight Video Oynatıcılarını Silverlight Streaming Servislerine yükleyebilirsiniz. Bunun için eklentiyi yükledikten sonra ilk yapmanız gereken Silverlight Streaming Servis hesabınızdan Account ID ve Account Key bilgilerini alarak Expression Encoder içerisine yerleştirmek.

Silverlight Streaming Serivis Bilgileri
Silverlight Streaming Serivis Bilgileri

Yukarıdaki görseldeki gibi http://silverlight.live.com/ adresinden sisteme Live ID'miz ile giriş yaptıktan sonra "Manage Account" kısmında gerekli bilgileri alarak direk Expression Encoder'da Output kısmına yerleştirebiliyoruz.

Expression Encoder içerisinde eklentiler.
Expression Encoder içerisinde eklentiler.

Expression Encoder içerisinde Output tabında yeni bir bölüm olarak "Publish" seçeneği karşımıza çıkıyor. Buradan Publish To kısmında "Silverlight Streaming" seçerek işlemimize devam edebiliriz. Bir sonraki adımda isterseniz yükleyeceğiniz video uygulaması için bir Application Name (Uygulama İsmi) tanımlayabilirsiniz. Son olarak Silverlight Stream Servisleri web sitesinden aldığımız Account ID ve Key'i de buraya yerleştirdiğimizde ayarlarımız tamamlanmış oluyor. Bölmenin alt kısmına doğru size bir IFRAME kodu veriliyor. Söz konusu IFRAME kodunu herhangi bir web sitesine kopyalayarak uygulamanın kendi sitenizde direk Silverlight Streaming Servisleri üzerinden çalıştırılmasını sağlayabilirsiniz. Eğer isterseniz en alt bölmeden daha önce Silverlight Streaming Servisleri'ne yüklediğiniz diğer uygulamaları silme veya görme şansınız da var.

Videonuzu bir kez Expression Encoder içerisinde bir Output Template (Şablon) seçerek Encode ettikten sonra Publish düğmesi aktif hale gelecektir. Hemen söz konusu düğmeye basarak yüklemeyi başlatabilirsiniz.

Videomuz Silverlight Streaming Servisleri'ne yükleniyor...
Videomuz Silverlight Streaming Servisleri'ne yükleniyor...

Hepinize kolay gelsin.

 

Tags:
Oca 01

WPF Windows uygulamalarında klasik Windows uygulamalarında olduğu gibi birden çok pencere açarak kullanıcıların farklı pencerelerde aynı anda işlem yapmalarını sağlayabilirsiniz. Bu işlemler yapılırken iki veya daha fazla pencere arasında gerçek zamanlı olarak veri aktarımı gerekebilir. Bu tip bir durumda WPF uygulamalarında kullanabileceğimiz Application objesi yardımımıza yetişiyor. Uygulama içerisindeki tüm XAML sayfaları ve Classlar Application objesine erişerek herhangi bir tipteki objeyi, değişkeni kaydedebilir veya okuyabilir. Bir örnek ile bu işlemleri nasıl yapabileceğimizi inceleyelim.

Ön Hazırlık

Visual Studio ile WPF uygulamaları yaratabilmek için sistemimizde .NET Framework 3.0 ve gerekli Visual Studio Extension'larının kurulu olması gerekiyor. Yükleme paketlerini aşağıdaki linklerden indirebilirsiniz.

http://www.microsoft.com/downloads/details.aspx?familyid=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en
http://www.microsoft.com/downloads/details.aspx?familyid=F54F5537-CC86-4BF5-AE44-F5A1E805680D&displaylang=en

Uygulama Açılışında Birden Çok Pencere Açmak

Visual Studio 2005 içerisinde yeni bir WPF Windows uygulaması başlatıyoruz. WPF Windows uygulamaları ilk açıldıklarında varsayılan pencereyi yüklerler. Bunun yanı sıra isterseniz farklı pencereleri de uygulama açılışında açabilirsiniz. Gerekli kodları yazmak üzere projemize ait App.xaml dosyasını açıyoruz.

' Interaction logic for App.xaml
Partial Public Class App
    Inherits System.Windows.Application
 
    Private Sub App_Startup(ByVal sender As Object, ByVal e As System.Windows.StartupEventArgs) Handles Me.Startup
        Dim x As New Window2
        x.Show()
    End Sub
End Class

Yukarıdaki kodumuzda Application'a ait StartUp durumunu kullanıyoruz. Uygulama ilk başlatıldığında Window2 adındaki penceremizden bir adet yaratarak kullanıcıya gösteriyoruz. Bu şekilde birden çok pencereyi uygulamanın ilk başında açmak mümkün. Açtığımız bu pencere kapatıldığında uygulamamızın da kapatılmasını istiyorsak söz konusu pencerelere aşağıdaki kodu yazmamız gerekecek.

    Private Sub Window2_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.Closing
        Application.Current.Shutdown()
    End Sub

Window2'ye ait Closing durumuna yazdığımız kod ile uygulamamızın tamamen kapatılmasını sağlıyoruz. Şimdi gelelim bu iki pencereyi birbiri ile konuşturmaya.

Farklı Pencerelerin İletişimi

Uygulalamızda ilk açılan pencere olan Window1 içerisinde aşağıdaki Class yapısını tanımlayalım.

    Public Class Adam
        Dim _Adi As String
        Dim _Soyadi As String
 
        Property Adi() As String
            Get
                Return _Adi
            End Get
            Set(ByVal value As String)
                _Adi = value
            End Set
        End Property
 
        Property Soyadi() As String
            Get
                Return _Soyadi
            End Get
            Set(ByVal value As String)
                _Soyadi = value
            End Set
        End Property
 
        Sub New()
 
        End Sub
 
        Sub New(ByVal Adi As String, ByVal Soyadi As String)
            Me.Adi = Adi
            Me.Soyadi = Soyadi
        End Sub
    End Class

Adam adındaki bu Class yapısı üzerinden bir adam değişkeni tanımlayacağız. Adam yapısına ait Adi ve Soyadi özelliklerine farklı değerler aktardıktan sonra bu yapıyı başka bir pencereyle paylaşacağız. İlk olarak gelin Window1'e ait XAML koduna bakalım.

Veri girişi yaptığımız WPF penceremiz.
Veri girişi yapacağımız WPF penceresi.

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF_Demo" Height="165" Width="301"
    >
    <Grid>
    <TextBox Height="26" ,
             Margin="51,16,142,0"
             Name="TextBox1"
             VerticalAlignment="Top"></TextBox>
    <Button Margin="52,51,0,58" Name="Button1"
            HorizontalAlignment="Left" Width="75">KAYDET</Button>
    <TextBox Height="26" HorizontalAlignment="Right"
             Margin="0,16,31,0" VerticalAlignment="Top"
             Width="100" Name="TextBox2" ></TextBox>
  </Grid>
</Window>

Penceremizde iki adet TextBox ve bir adet Button bulunuyor. Düğmeye tıklandığında aşağıdaki kod çalışarak kutular içerisinde yazan bilgiler çerçevesinde bir adam değişkeni yaratacak ve adını, soyadını belirleyecek. Sonrasında da sihirli kodumuzu kullanarak Application Class'ı ile veriyi kaydedecek.

    Private Sub Kaydet_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Dim YeniAdam As New Adam(TextBox1.Text, TextBox2.Text)
        If Application.Current.Properties.Contains("Sahip") = False Then
            Application.Current.Properties.Add("Sahip", YeniAdam)
        Else
            Application.Current.Properties.Item("Sahip") = YeniAdam
        End If
    End Sub

Kodumuzda YeniAdam adındaki değişkenimizi yarattıktan sonra Application.Current diyerek mevcut uygulamayı yakalıyoruz. Mevcut uygulamanın Properties listesine farklı isimler vererek kayıtlar koyabiliriz. Bizim kaydımızın ismi Sahip olacak. Kayıt daha önce varsa sadece değiştiriyoruz. .Contains metodu ile kaydın daha önce eklenip eklenmediğini kontrol edebilirsiniz.

Kaydetme işlemimiz tamamlandığında göre Window2 penceremize ait XAML kodunu inceleyerek çalışmalarımıza Window2 üzerinde devam edelim.

<Window x:Class="Window2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF_Demo" Height="135" Width="289"
    >
    <Grid>
    <Button Margin="81,34,125,45" Name="Button1">Sahip Kim?</Button>
  </Grid>
</Window>

Window2 içerisinde sadece bir adet Button var. Düğmeye tıkladığımızda Window1 tarafından kaydedilen bilgiyi okuyarak kullanıcıya birer mesaj kutusu ile basit bir şekilde göstereceğiz. Kodumuz aşağıdaki şekilde olacak.

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        MessageBox.Show(Application.Current.Properties.Item("Sahip").adi)
        MessageBox.Show(Application.Current.Properties.Item("Sahip").soyadi)
    End Sub

Gördüğünüz gibi yine Application.Current diyerek uygulamamızın tüm Properties listesine ulaşabiliyoruz. Burada Sahip adındaki bilgiyi alarak aldığımız kişi değişkeninin Adi ve Soyadi özelliklerine ulaşabiliyoruz. Böylece her iki pencere de açıkken birinde yapılan değişiklikler kaydedilebilirken diğerinden de direk okunabilir veya her iki pencere de aynı obje üzerinde değişiklikler yapabilir. Değişiklikerin pencereler tarafından algılanmasını isterseniz Actived durumlarında Application üzerinden veriler tekrar alabilirsiniz.

Hepinize kolay gelsin.

Örnek Uygulama Kaynak Dosyaları - 05092007_1.zip (417,09 KB)

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

WPF uygulamarında görsel öğelerin ön planda olduğu kesin. Bu noktada uzmanı olmamız gereken konulardan biri de tetikleyicileri (trigger) nasıl kullanacağımızı bilmek olacaktır. Farklı tetikleyiciler ile WPF uygulamarımızdaki nesnelerin görsel özellikleri üzerinde değişiklikler yapabilir ve interaktivite katabiliriz. Makalemiz boyunca tetikleyicilarin kullanımına ve çeşitlerine değineceğiz.

Nitelik (Property) Bazlı Tetikleyiciler

İlk aşamada inceleyeceğimiz tetikliyici tipi belki de kullanımı en sade ve kolay anlaşılır olan tip. Farklı nesnelerin niteliklerindeki değişiklikler ve öne süreceğimiz şartlar çerçevesinde başka nesnelerin görsel özellikleri üzerinde değişiklik yapmamızı sağlayacak nitelik bazlı tetikleyiciler ile ilgili gelin hemen bir örnek yapalım. İlk olarak tetikleyicimizi yerleştireceğimiz görsel özellikleri de içerecek olan stil objemizi yani taglarımızı yazalım.

<Style TargetType="{x:Type TextBox}">

Tagımızı yazarken TargetType özelliği vererek WPF uygulamamız içerisinde tüm TextBox tipindeki objelere uygulanmasını sağlıyoruz.

<Style.Triggers>

Stilimize ait tetikliyicileri Style.Triggers tagları arasına yerleştiriyor olacağız.

<Trigger Property="IsMouseOver" Value="True">

Geldik tetikleyicimizi tanımladığımız kodlara. Hedef kontrolün, yani bizim örneğimizde TextBox'ın IsMouseOver özelliği True olduğunda çalışacak şekilde bir tetikleyici tanımladık. Tetikleyicinin kontrol edeceği hedef kontroldeki özelliğin adını Property parametresine değer olarak aktardıktan sonra karşılaştıracağımız değeri de Value parametresine veriyoruz. Böylece sayfadaki herhangi bir TextBox'ın fare ile üzerine gelindiğinde IsMouseOver özelliği True olacak ve bizim de tetikleyicimiz çalışacak. Peki çalışıp da ne yapacak?

<Setter Property="Background" Value="Red" />

Yukarıdaki kodumuz ile bir anlamda bir "tanımlayıcı" tanımlıyoruz ve hedef kontrolün herhangi bir özelliğini istediğimiz bir değere eşitleyebiliyoruz. Bizim kodumuzda hedef kontrolün Background özelliği Red yani kırmızı olarak ayarladık. Şimdi gelin WPF uygulamamızın tam koduna bir göz atalım.

WPF kodumuz içerisinde tanımladığımız tetikleyicilerimiz ile TextBox otomatik kırmızı oluyor.
WPF kodumuz içerisinde tanımladığımız
tetikleyicilerimiz ile TextBox otomatik kırmızı oluyor.

window1.xaml

<
Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="Window1"
       x:Name="Window"
       Title="Window1"
       Width="320" Height="240">
       <Window.Resources>
             <Style TargetType="{x:Type TextBox}">
                    <Style.Triggers>
                           <Trigger Property="IsMouseOver" Value="True">
                                  <Setter Property="Background" Value="Red" />
                           </Trigger>
                    </Style.Triggers>
             </Style>
       </Window.Resources>
       <Grid x:Name="LayoutRoot">
             <TextBox Margin="35,48,66,0" VerticalAlignment="Top"
                    Height="33" Text="TextBox" TextWrapping="Wrap"/>
       </Grid>
</Window>

Uygulamamız içerisinde yer alan metin kutusu yine uygulamamızın Window.Resources kısmında tanımladığımız stiller tarafından etkilenecek. Stilimiz içerisinde tanımladığımız tetkileyiciler gerektiğinde çalışarak metin kutusunun fonunu kırmızı yapacak.

Çok Şartlı Tetikleyiciler

Tetikleyicileri farklı kontrollerin özellikleri üzerinden nasıl kullanabileceğimize baktıktan sonra sıra geldi birden fazla koşulu kontrol ederek tetikleyicilerimizi çalıştırmaya. Bir sonraki örneğimizde yine bir metin kutusu kullanacağız, fakat bu sefer sadece fare ile metin kutusu üzerine gelinmesini değil aynı anda metin kutusunun içerisinde "Sihirli Kelime" yazmasını da kontrol edeceğiz. Eğer metin kutusu içerisinde "Sihirli Kelime" yazıyorsa fare ile üzerine geldiğimizde metin kutusunun fon rengi değişecek. Böylece metin kutusuna ait iki farklı niteliği kontrol etmiş olacağız.

<MultiTrigger>

Kullanacağımız esas tag MultiTrigger tagı olacak. MultiTrigger içerisinde istediğiniz sayıda farklı Trigger'lar tanımlayabilirsiniz.

<MultiTrigger.Conditions>

Her bir MultiTrigger'ın birden çok koşulu olabildiğinden bahsetmiştik. Bu koşullarımızı MultiTrigger.Conditions tagları arasına yazmamız gerekiyor.

<Condition Property="IsMouseOver" Value="True" />

İşte ilk şartımızı tanımlıyoruz. Bir önceki örneğimizdeki ile aynı özellikleri vererek tanımladığımız şartımızda hedef kontrolün IsMouseOver durumunun True olup olmadığı kontrol edilecek.

<Condition Property="Text" Value="Sihirli Kelime" />

İkinci şartımızı da yukarıdaki şekilde tanımlıyoruz. Şartımız hedef kontrolün Text özelliğinin yani TextBox'ın içeriğinin "Sihirli Kelime" metnine eşit olması.

<Setter Property="Background" Value="Green" />

Şartlarımızı tamamladıktan sonra son olarak da yapacağımız işlemi yine bir önceki bölümdeki ile aynı şekilde tanımlıyoruz. Oluşturduğumuz kodun son halini aşağıda inceleyebilirsiniz.

WPF uygulamamızda iki farklı koşulu kontrol ederek metin kutusunun fon rengini değiştiyoruz.
WPF uygulamamızda iki farklı koşulu kontrol ederek
metin kutusunun fon rengini değiştiyoruz.

window2.xaml

<
Window
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="Window2"
       x:Name="Window"
       Title="Window2"
       Width="320" Height="240">
       <Window.Resources>
             <Style TargetType="{x:Type TextBox}">
                    <Style.Triggers>
                           <MultiTrigger>
                                  <MultiTrigger.Conditions>
                                        <Condition Property="IsMouseOver" Value="True" />
                                        <Condition Property="Text" Value="Sihirli Kelime" />
                                  </MultiTrigger.Conditions>
                                  <Setter Property="Background" Value="Green" />
                           </MultiTrigger>
                    </Style.Triggers>
             </Style>
       </Window.Resources>
       <Grid x:Name="LayoutRoot">
             <TextBox Margin="55,88,65,72" Text="TextBox" TextWrapping="Wrap"/>
       </Grid>
</Window>

WPF uygulamamızda yine bir TextBox nesnesi var. Metin kutusu içerisinde "Sihirli Kelime" yazdığımızda ve fare ile üzerine geldiğimizde her iki koşul da yerine getirildiği için metin kutusunun fon rengi yeşile dönüyor.

Hepinize kolay gelsin.

Örneklere ait kaynak kodları - 06092007_3.zip (141,21 KB)

Tags:
Oca 01

Expression Studio içerisinde bulunan Expression Blend bir animasyon tasarım aracı olarak bize WPF Windows uygulamaları tasarlama olanağı tanıyor. Artık Windows uygulamalarında iki veya üç boyutlu animasyonlar kullanmak gerçekten çok kolay. Son yaptığımız Expression Blend webinerine katılanlar demolarda bu kolaylığın farkına varmışlardır. Bu kadar animasyonlardan bahsettikten sonra bir animasyon örneği vereceğimizi düşünüyorsanız, haklısınız ama yanılıyorsunuz :)

WPF uygulamalarında kullanabileceğimiz farklı kontroller var. Eski Windows uygulamalarından alıştığımız Button, Label vs kontrollerin yanı sıra çok kullanışlı ve ilginç kontroller mevcut. Bu kontrollerden özellikle FlowDocumentReader kontrolü çok hızlı birşekilde işlevsel uygulamalar hazırlamanızı sağlayabilir. Gelin şimdi hemen Expression Blend ile bir WPF Windows Application yaratalım.

Yeni bir WPF Windows uygulaması yaratıyoruz.
Yeni bir WPF Windows uygulaması yaratıyoruz.

Uygulamamızı yarattıktan sonra içerisinde bir adet FlowDocumentReader kontrolü yerleştireceğiz. Bu kontrolü direk araç çubuğunda bulma şansınız yok. O nedenle araç çubuğundan "Asset Library" kısmına giderek kontrolümüzü orada bulmamız gerekecek.

FlowDocumentReader kontrolümüzü Asset Library içerisinde buluyoruz.
FlowDocumentReader kontrolümüzü Asset Library içerisinde buluyoruz.

Kontrolü uygulamamızdaki Window1 penceresine yerleştirdikten sonra kontrolümüze flowDoc adını vererek genişliğini ve yüksekliğini ayarlıyoruz. Son olarak da pencereye bir Button yerleştirerek içerisine de Content özelliğine "Doküman Aç" değerini vererek gerekli bilgiyi yazmış olduk. Window1.xaml dosyasının XAML kodları aşağıdaki şekilde sonuçlanıyor.

<Window

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

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

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

 

  <Grid x:Name="LayoutRoot">

    <FlowDocumentReader Margin="0,0,0,50" x:Name="flowDoc"/>

    <Button HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="136" Height="30" Content="Doküman Aç"/>

  </Grid>

</Window>

 

Programımızın tasarımını bitirdik. Sıra geldi kodlamaya. Penceremizdeki düğmeye basıldığında klasik Windows doküman açma dialoğunun gelmesini ve seçilen bir XAML dokümanını programımızda gösterilmesini istiyoruz. Burada özellikle bir detayı belirtmem gerek; programımızın açacağı XAML dosyaları FlowDocument formatında olmalı. Yani bunlar herhangi bir XAML dosyası olamaz. Bu dokümanların nasıl yaratılacağına ileride değineceğim ama şimdilik gelin örnek bir XAML dokümanını inceleyelim.

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

  <Table CellSpacing="5">

 

    <Table.Columns>

      <TableColumn/>

      <TableColumn/>

      <TableColumn/>

      <TableColumn/>

    </Table.Columns>

 

    <TableRowGroup>

 

      <TableRow Background="SkyBlue">

        <TableCell ColumnSpan="4" TextAlignment="Center">

          <Paragraph FontSize="24pt" FontWeight="Bold">Gezegen Bilgileri</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow Background="LightGoldenrodYellow">

        <TableCell>

          <Paragraph FontSize="14pt" FontWeight="Bold">Gezegen</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph FontSize="14pt" FontWeight="Bold">Güneşten Mesafe</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph FontSize="14pt" FontWeight="Bold">Çap</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph FontSize="14pt" FontWeight="Bold">Kütle</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow>

        <TableCell ColumnSpan="4">

          <Paragraph FontSize="14pt" FontWeight="Bold">İç Gezegenler</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow>

        <TableCell>

          <Paragraph>Merkür</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>57,910,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>4,880 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>3.30e23 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow Background="lightgray">

        <TableCell>

          <Paragraph>Venus</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>108,200,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>12,103.6 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>4.869e24 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow>

        <TableCell>

          <Paragraph>Dünya</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>149,600,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>12,756.3 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>5.972e24 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow Background="lightgray">

        <TableCell>

          <Paragraph>Mars</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>227,940,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>6,794 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>6.4219e23 kg</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow>

        <TableCell ColumnSpan="4">

          <Paragraph FontSize="14pt" FontWeight="Bold">Dış Gezegenler</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow>

        <TableCell>

          <Paragraph>Jupiter</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>778,330,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>142,984 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>1.900e27 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow Background="lightgray">

        <TableCell>

          <Paragraph>Satürn</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>1,429,400,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>120,536 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>5.68e26 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow>

        <TableCell>

          <Paragraph>Uranüs</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>2,870,990,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>51,118 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>8.683e25 kg</Paragraph>

        </TableCell>

      </TableRow>

      <TableRow Background="lightgray">

        <TableCell>

          <Paragraph>Neptün</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>4,504,000,000 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>49,532 km</Paragraph>

        </TableCell>

        <TableCell>

          <Paragraph>1.0247e26 kg</Paragraph>

        </TableCell>

      </TableRow>

 

      <TableRow>

        <TableCell ColumnSpan="4">

          <Paragraph FontSize="10pt" FontStyle="Italic">

            Kaynak:

            <Hyperlink NavigateUri="http://encarta.msn.com/encnet/refpages/artcenter.aspx">Encarta</Hyperlink>

            web sitesi.

          </Paragraph>

        </TableCell>

      </TableRow>

 

    </TableRowGroup>

  </Table>

</FlowDocument>

 

Bir FlowDocument'ın nasıl yaratılacağı ile ilgili detaylara girmeyeceğim. Ama sanırım yukarıda her şey yeterince açıktır. FlowDocument'ları Tag isimleri farklı birer HTML dokümanına benzetebilirsiniz. Programımız yukarıdaki şekilde düzenlenmiş belgeleri açabilecek.

Sıra geldi artık programlama kodumuzu yazmaya. Bunun için Expression Blend içerisinde düğmemizi seçerek sağ sütunda "Properties" sekmesine geçeceğiz. "Properties" sekmesi içerisinde de "Events" bölümüne geçtikten sonra "Click" özelliğine istediğimiz bir method adı yazacağız.

Düğmemizin Click durumuna ait methodu tanımlıyoruz.
Düğmemizin Click durumuna ait methodu tanımlıyoruz.

Yukarıdaki gibi DocAcTiklandi değerini yazdığınız Expression Blend size gerekli Event kodunuzu verecektir. Eğer bilgisayarınızda Visual Studio ve WPF Extension yüklü ise direk Visual Studio içerisinde projeniz açılacaktır. İlk baktığımızda aşağıdaki kodun otomatik olarak eklendiğini görüyoruz.

    Private Sub DokAcTiklandi(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

 

    End Sub

 

Programımızın Window1.xaml dosyasının XAML kodlarına baktığımızda ise ufak bir değişiklik görebiliriz.

<Window

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

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

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

 

  <Grid x:Name="LayoutRoot">

    <FlowDocumentReader Margin="0,0,0,50" x:Name="flowDoc"/>

    <Button HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="136" Height="30" Content="Doküman Aç" Click="DokAcTiklandi"/>

  </Grid>

</Window>

 

XAML kodlarına dikkatli olarak bakarsak artık Button nesnesine ait Click özelliğinin bizim için otomatik olarak ayarlanmış olduğunu görebiliriz. Bu noktadan sonra bizim tek yapmamız gereken uygun kodları Visual Studio içerisinde yazmak. İlk olarak aşağıdaki kod ile penceredeki FlowDocumentReader nesnesini bulacağım. Aslında buna normal şartlarda gerek yok, fakat bazen Visual Studio içerisinde Intellisense XAML kodundaki objeleri yakalayamıyor. Bunun nedeni büyük ihtimal ile tüm bu XAML desteğinin bir Extension olarak yükleniyor olması. Visual Studio 2008 ile yaptığım denemelerde böyle bir sorunla karşılaşmadım. O nedenle eğer siz de aynı sorunla karşılaşırsanız aşağıdaki kod ile kontrolümüzü yakalayabilirsiniz.

Dim flowDoc As FlowDocumentReader = CType(Me.FindName("flowDoc"), FlowDocumentReader)

 

Sonraki adımda ilk olarak kendimize özel bir FlowDocument nesnesi tanımlayacağız. Kullanıcının doküman açabilmesi için eski Windows uygulamalarında da kullandığımız OpenFileDialog nesnesinden yardım alacağız.

        Dim yeniDoc As Documents.FlowDocument = Nothing

        Dim Dialog As New Microsoft.Win32.OpenFileDialog

        Dialog.Filter = "FlowDocument Dosyaları (*.xaml)|*.xaml"

        If Dialog.ShowDialog.Value Then

 

        End If

 

Eğer OpenFileDialog ile kullanıcı bir dosya seçmiş ise sıra gelecek dosyayı okuyarak daha önce yarattığımız FlowDocument değişkenimiz olan yeniDoc değişkenine aktarmaya.

            Dim xamlDosya As FileStream = CType(Dialog.OpenFile, FileStream)

            Try

                yeniDoc = CType(Markup.XamlReader.Load(xamlDosya), Documents.FlowDocument)

                flowDoc.Document = yeniDoc

            Catch ex As Exception

                System.Windows.MessageBox.Show(ex.Message)

            End Try

 

Yukarıdaki kod içerisinde ilk satırda xamlDosya adında bir FileStream yaratarak dosyamızın konumunu alıyoruz. Sonrasında dosya okuma işlemini Try-Catch bloğu içerisinde gerçekleştireceğiz. En baştayarattığımız yeniDoc FlowDocument değişkenimize gerçek dosyayı okuyarak yüklemek için Markup.XamlReader sınıfını kullanıyoruz. Xaml dosyası okunduktan sonra değişken tipini de FlowDocument'a çevirerek kendi yeniDoc nesnemize aktardık. Artık elimizdeki FlowDocument değişkenimiz penceremizdeki FlowDocumentReader'a aktarılmaya hazır. FlowDocumentReader'a ait Document özelliğine gerekli değeri aktararak okuma işlemini sonlandırabiliriz. Tüm bu işlemler süresince eğer bir hata gerçekleşirse hatayı bir mesaj kutusu olarak Try-Catch bloğu ile kullanıcıya gösterebiliyoruz.

Artık programımızı deneyebiliriz. Visual Studio veya Expression Blend içerisinde F5'e bastığınızda program derlenecek ve otomatik olarak çalıştırılacaktır. Yukarıda örnek olarak verdiğimiz FlowDocument XAML dosyasını açtığımızda aşağıdaki gibi bir ekranla karşılaşıyoruz.

WPF uygulamamızda FlowDocumentReader görüntüsü.
WPF uygulamamızda FlowDocumentReader görüntüsü.

Gördüğünüz gibi dosyamız programımızda gösteriliyor. Peki neden FlowDocumentReader? FlowDocumentReader'ın özellikleri tek tek yazarak anlatmaya çalışmaktansa gelin aşağıda ufak bir seri görüntü ile durumu inceleyelim.

FlowDocument içerisinde otomatik sayfalama.
FlowDocument içerisinde otomatik sayfalama.

FlowDocumentReader kontrolünün kendi içerisinde bazı özellikleri var. Bunlardan ilki programın kullanıcısına açılan dokümanı farklı şekillerde okuyabilme olanağı sağlıyor olması. Yukarıdaki ekran görüntüsünde kullanıcı dokümanı sayfalar şeklinde görmek istediği için FlowDocumentReader gerekli düzenlemeleri otomatik olarak yapmış. Tüm bu işlemlerin tamamen vektörel olarak yapıldığını bu nedenle her şekilde yazılarda ve grafiklerde çok net görüntüler alındığını özellikle belirtmek istiyoruz.

FlowDocumentReader'da zoom yapmak arama yapmak kadar kolay.
FlowDocumentReader'da zoom yapmak arama yapmak kadar kolay.

FlowDocumentReader kontrolü ile beraber gelen diğer özellikler de çok etkileyici. Kullanıcı istediği zaman dokümana zoom yapabiliyor. Yukarıdaki görüntüde dokümanın biraz büyütülmüş halini görebilirsiniz. Yazılarda herhangi bir bozulma yok. Aynı şekilde kullanıcı isterse yazıların boyutu FlowDocumentReader'ın sağ altında bulunan kontroller ile küçültebilir de. Son olarak bahsetmek istediğim belki de en önemli işlevlerden biri de Arama. FlowDocumentReader ile beraber otomatik bir arama motoru geliyor ve açılan doküman içerisinde aramaları FlowDocumentReader tamamen kendisi yapıyor.

Sanırım artık neden bu yazımda FlowDocumentReader'ı anlatmak istediğimizi anlamışsınızdır. Tabiri caiz ise iki satır kod yazarak muhteşem bir program yapmış olduk. WPF olmadan önce bu tarz bir programı hazırlamak belki de bir haftamızı alırdı.

FlowDocument Dosyaları nasıl yaratılır?

Gelelim can alıcı soruya. Eminim ki çoğunuz şu anda elinizdeki bir sürü dokümanı yukarıdaki şekilde windows uygulamaları ile göstermek müşterilerinize projelerde göstermek istiyorsunuz. Daha önce de bahsettiğim gibi HTML ile FlowDocument yazımı arasında ciddi benzerlikler var. Bu noktada HTML'den FlowDocument'a yani XAML'e çevirmek için gerekli araçlar da hazır. Aşağıdaki adresten XAML'den HTML'e veya tam tersi HTML'den XAML'e çeviri yapabilen bir yazılımı açık kaynak kodu ile indirebilirsiniz.

http://wpf.netfx3.com/files/folders/developer/entry816.aspx

Makale boyunca yaptığımız örneğin kodlarını da aşağıdan indirebilirsiniz.

WPF FlowDocumentReader Proje Kaynak Kodları - 20102007_1.zip (137,43 KB)

Hepinize kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

XBAP da ne ola ki?

XBAP'ın açılımı "XAML Browser Applications" şeklinde. Peki XAML neydi? Extensible Application Markup Language, yani WPF (Windows Presentation Foundation) ile beraber gelen XML yapısında görsel, vektörel içeriklerin tanımlandığı bir model. XAML aynı anda Silverlight içerisinde de görsel arayüzü modellemek, animasyonları hazırlamak için kullandığımız yapının ta kendisi. Daha önceki yazılarımda bu konulardan bahsettiğim için XAML'in veya WPF'in çok detaylarına girmeyeceğim.

WPF'de yapabildiğiniz herşeyi Browser'a taşıyın!

XBAP işte tam olarak bu işi yapıyor. WPF Browser Application olarak da tanımlayabileceğimiz bu uygulamalar tamamen internet üzerinden çalışarak istemcideki tarayıcının içerisinde sunuluyor. Hemen aşağıdaki linklerden birkaç örnek incelemenizi tavsiye ediyorum. Sonrasında konumuza devam edelim.

http://scorbs.com/workapps/woodgrove/FinanceApplication.xbap
http://ttpdownload.bl.uk/browserapp.xbap
http://scorbs.com/workapps/photobook/PhotoBook.xbap

Örnekleri incelediyseniz özellikle ilk örnekteki 3 boyutlu grafikler dikkatinizi çekmiştir. WPF'in 3D desteği olduğunu biliyoruz, bu çerçevede hazırladığımız herhangi bir WPF 3D uygulamasını hemen WFP Browser Application olarak çevirerek internette yayınlama şansımız da var. Maalesef şu an ne Silverlight ne de Flash'ın böyle bir desteği yok.

Silverlight, WPF, XBAP? Nedir bunların farkı?

Programlama açısından XBAP ile WPF arasındaki fark çok az. XBAP bir internet tarayıcı içerisinde (Sadece Internet Explorer) çalıştığı için bazı ek güvenlik sınırlamaların maruz kalıyor. WPF ise zaten bildiğimiz windows programlarından farksız. Hem XBAP hem de WPF'de tüm .NET dillerini (VB.NET, C# vs) kullanabiliyoruz. XBAP'ın avantajı bir HTTPRequest ile karşı tarafta internet tarayıcıya yüklenerek hemen çalıştırılabiliyor olması. Fakat bu noktada özellikle belirtmem gereken bir nokta var; istemci bilgisayarda .NET Framework 3.0'ın yüklü olması şart! Aksi halde uygulama çalışmayacaktır. Bunun için bir ASP.NET sitesi hazırlayarak ilk aşamada kullanıcının bilgisayarında .NET Framework 3.0'ın yüklü olup olmadığı incelenerek uygun mesajlar verilebilir ama her halükarda istemcileri Windows XP SP2 ve Vista ile sınırlamış oluyorsunuz.

Silverlight zaten apayrı bir dünya. İstemcide .NET Framework 3.0 vs yüklü olmasa da sadece Silverlight Plug-In yüklü ise Macintosh dahil tüm cihazlarda çalışacaktır. WPF ile XBAP arasındaki kadar büyük bir yakınlık olmasa da Silverlight da WPF'in ufak bir parçası aslında. Silverlight şu anki 1.0 sürümünde JavaScript, ileride ise .NET dilleri ile programlanabilecek fakat yine de kullanılan .NET sınıfları da sınırlı olacak ve XBAP gibi geniş olanaklara sahip olmayacak.

Ufak bir örnek yapalım.

Şimdi çok ufak bir WPF windows uygulaması hazırlayalım ve aynı uygulamayı WPF Browser Application yapmanın ne kadar kolay olduğunu inceleyelim. Tüm bunları yaparken Visual Studio 2008 kullanacağım. VS 2005 ile WPF Browser Application Proje Şablonu gelmiyor ve bazı işlemleri elle yapmak gerekiyor. O nedenle Visual Studio 2005 ile hiç uğraşmayarak doğrudan Visual Studio 2008 kullanacağım. Önümüzdeki bir ayı takiben tüm örneklerimi de VS 2008 ile yapıyor olacağım. Eğer hala VS 2008 Beta 2 edinmediyseniz hemen bilgisayarınıza indirmenizi tavsiye ederim. Bu konuda aşağıdaki yazımı inceleyebilirsiniz.

Visual Studio 2008 Virtual PC İmajları Yenilendi

Expression Blend 2 Beta September Preview kullanarak yeni bir WPF Application yaratarak otomatik olarak gelen uygulamanın ana penceresi üzerine bir dikdörtgen koyarak ufak bir animasyon tanımladım. Bunu takiben bir de pencereme düğme koyarak önceden hazırladığım animasyonu bu düğmeye bağladım. Window1.XAML'in kodu aşağıdaki şekilde sonlandı.

<Window

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

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

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="300" Height="300">

 

  <Window.Resources>

    <Storyboard x:Key="OrnekAnimasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="91"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="93"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Window.Resources>

 

  <Window.Triggers>

    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">

      <BeginStoryboard Storyboard="{StaticResource OrnekAnimasyon}"/>

    </EventTrigger>

  </Window.Triggers>

 

  <Grid x:Name="LayoutRoot">

    <Rectangle Margin="18,34,131,128" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle" RenderTransformOrigin="0.5,0.5">

      <Rectangle.RenderTransform>

        <TransformGroup>

          <ScaleTransform ScaleX="1" ScaleY="1"/>

          <SkewTransform AngleX="0" AngleY="0"/>

          <RotateTransform Angle="0"/>

          <TranslateTransform X="0" Y="0"/>

        </TransformGroup>

      </Rectangle.RenderTransform>

    </Rectangle>

    <Button HorizontalAlignment="Left" Margin="18,0,0,8" VerticalAlignment="Bottom" Width="81" Height="36" Content="Button" x:Name="button"/>

  </Grid>

</Window>

Şu an hala bir windows programı üzerinde çalıştığımızı aşağıdaki basit ekran görüntüsünü inceleyerek tekrar hatırlayalım :)

Örnek WPF Uygulamamız
Örnek WPF Uygulamamız

Şimdi biraz .NET kodu yazmak için Blend'de hazırladığım projemi Visual Studio ile açarak hazırlamış olduğum animasyonun bitişinde çalıştırılmak üzere aşağıdaki kodu yazacağım.

Imports System

Imports System.IO

Imports System.Net

Imports System.Windows

Imports System.Windows.Controls

Imports System.Windows.Data

Imports System.Windows.Media

Imports System.Windows.Media.Animation

Imports System.Windows.Navigation

 

Partial Public Class Window1

    Dim WithEvents Animasyonum As Storyboard

    Public Sub New()

        MyBase.New()

 

        Me.InitializeComponent()

 

        ' Insert code required on object creation below this point.

    End Sub

 

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

        Animasyonum = CType(Me.Resources.Item("OrnekAnimasyon"), Storyboard)

    End Sub

 

    Private Sub Animasyon_Bitti(ByVal sender As Object, ByVal e As System.EventArgs) Handles Animasyonum.Completed

        Microsoft.VisualBasic.MsgBox("Bitti")

    End Sub

End Class

Sıra geldi uygulamamızı aynen bir WPF Browser Application'a çevirmeye. Bunun için ilk olarak Visual Studio 2008 içerisine yeni bir WPF Browser Application yaratmamız gerekiyor.

Visual Studio 2008 ile WPF Browser Application yaratıyoruz.
Visual Studio 2008 ile WPF Browser Application yaratıyoruz.

Projemizi yarattıktan sonra ilk olarak XAML kodlarımızı kopyalayacağız. Visual Studio ile WPF Browser Application'ımızı yarattıktan sonra bizim için otomatik olarak boş bir XAML Page de yaratılmış oluyor. Page1.XAML olarak geçen dosyanın içeriğine gelin hızlıca bir göz atalım.

<Page x:Class="Page1"

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

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

    Title="Page1">

  <Grid>

 

  </Grid>

</Page>

Hmm... Peki bunun herhangi bir WPF uygulamanın bir penceresinden farkı nedir? Onun da içerisinde Grid yok muydu? Evet, aynen öyle. Aradaki fark WPF uygulamalarda Window'lar varken XAML Browser Application'larda Page'lerin olması. Yani sadece XML dosyasında kök element değişiyor. O nedenle WPF windows uygulamamızda Window tagları arasında yer alan tüm XAML kodunu kopyalayarak burada Page taglarının arasına koymamız gerekiyor. Zaten bu nedenle bir önceki örnekteki XAML kodunda Window taglarını koyu olarak yazmıştım :) Bakalım tüm bu işlemleri yapınca WPF Browser Application'ımızın Page1.XAML dosyası ne hale geliyor.

<Page x:Class="Page1"

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

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

    Title="Page1">

 

  <Page.Resources>

    <Storyboard x:Key="OrnekAnimasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="91"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="93"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Page.Resources>

 

  <Page.Triggers>

    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button">

      <BeginStoryboard Storyboard="{StaticResource OrnekAnimasyon}"/>

    </EventTrigger>

  </Page.Triggers>

 

  <Grid x:Name="LayoutRoot">

    <Rectangle Margin="18,34,131,128" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle" RenderTransformOrigin="0.5,0.5">

      <Rectangle.RenderTransform>

        <TransformGroup>

          <ScaleTransform ScaleX="1" ScaleY="1"/>

          <SkewTransform AngleX="0" AngleY="0"/>

          <RotateTransform Angle="0"/>

          <TranslateTransform X="0" Y="0"/>

        </TransformGroup>

      </Rectangle.RenderTransform>

    </Rectangle>

    <Button HorizontalAlignment="Left" Margin="18,0,0,8" VerticalAlignment="Bottom" Width="81" Height="36" Content="Button" x:Name="button"/>

  </Grid>

</Page>

Yukarıdaki kodu incelerseniz özellikle kalın olarak yazılmış 4 satır kod göreceksiniz. Bunlar sayfamızdaki Trigger (Tetikleyiciler) ve Ressources (Kaynaklar) ile ilgili tanımlamaların bulunduğu bölümler. Bu bölümlerin tag isimlerinde WPF uygulamamızda "Window" yazıyordu, onları "Page" olarak değiştirmemiz gerekti, çünkü artık bir Window değil Page içerisinde çalışıyoruz.

Sıra geldi VB ile yazdığımız kodları da WPF Browser Application tarafına taşımaya. Gelin yine Page1.XAML'in boş VB sayfasına göz atalım.

Class Page1

 

End Class

Epey basit değil mi? :) Eh gelin o zaman kodlarımızı kopyalayalım.

Imports System.Windows.Media.Animation

 

Class Page1

    Dim WithEvents Animasyonum As Storyboard

 

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

        Animasyonum = CType(Me.Resources.Item("OrnekAnimasyon"), Storyboard)

    End Sub

 

    Private Sub Animasyon_Bitti(ByVal sender As Object, ByVal e As System.EventArgs) Handles Animasyonum.Completed

        Microsoft.VisualBasic.MsgBox("Bitti")

    End Sub

End Class

Aynı kodları bire bir "copy-past" :) Hiçbir değişiklik gerekmeden uygulamamızı artık F5 tuşu ile Internet Explorer içerisinde çalıştırabiliriz.

XBAP - WPF Browser Application iş başında.
XBAP - WPF Browser Application iş başında.

Hızlı ilerlemek ve konsepti gösterebilmek adına yine çok basit bir örnek olduğunun farkındayım fakat hayal gücünüzü kullanmak tabi ki size kalmış. WPF içerisinde yapılabilen (neredeyse) herşeyi WPF Browser Application'lar ile yapmak da mümkün.

Hepinize kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

WPF release olduğundan bu yana neredeyse tüm eğitimlerde ve seminerlerde WPF ile klasik Winforms yapısının aynı uygulama içerisinde beraber kullanılıp kullanılmayacağı sorusu ile karşılaşıyorum. Bu yazıda klasik bir Winforms uygulamasında WPF kullanmanın yolunu inceleyeceğiz.

İlk olarak Visual Studio 2008 ile .NET Framework 3.5 altyapısında bir Winforms uygulaması yaratıyoruz. Solution Explorer içerisinde projeye sağ tuş ile tıkladığımızda gelen menüden "Add / New Item" dediğimizde WPF altında sadece WPF User Control ekleyebildiğimizi görüyoruz. Hemen projemizde bir WPF User Control ekleyerek yolumuza devam edelim. Tüm WPF uygulamalarında olduğu gibi WPF User Control'lerin de görsel yapısının Expression Blend ile düzenlenmesi gerekiyor. Bu amaçlı projemizi (proje dosyasını) Expression Blend ile de açıyoruz ve WPF User Control içerisinde aşağıdaki şekliyle ufak bir animasyon düzenliyoruz.

<UserControl x:Class="UserControl1"

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

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

            Width="300"

            Height="300">

  <UserControl.Resources>

    <Storyboard x:Key="Storyboard1">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                    Storyboard.TargetName="rectangle"

                                    Storyboard.TargetProperty="(UIElement.Opacity)">

        <SplineDoubleKeyFrame KeyTime="00:00:00"

                            Value="1" />

        <SplineDoubleKeyFrame KeyTime="00:00:01"

                            Value="0.4" />

        <SplineDoubleKeyFrame KeyTime="00:00:02"

                            Value="1" />

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </UserControl.Resources>

  <Grid>

    <Rectangle Margin="0,0,0,0"

              Fill="#FFFF0000"

              Stroke="#FF000000"

              x:Name="rectangle" />

  </Grid>

</UserControl>

User Control içerisine tam boyutta yerleştirilmiş olan bir dikdörtgene ait Storyboard1 adındaki animasyon söz konusu dikdörtgenin şeffaflık değerlerini değiştirerek basit bir animasyon oluşturuyor. Şimdi sıra geldi bu WPF User Control'ü Winforms penceresine eklemeye. Winforms pencerelerinde bir WPF User Control kullanabilmek için ilk olarak araç çubuğunda "WPF Interoperability" sekmesinden formumuza bir ElementHost kontrolü eklememiz gerekiyor.

WPF User Control host edecek olan ElementHost kontrolünü forma yerleştiriyoruz.
WPF User Control host edecek olan ElementHost kontrolünü forma yerleştiriyoruz.

ElementHost kontrolünü forma ekledikten sonra hemen kontrolün sağ üst köşesindeki ufak üçgene tıklayarak gelen menüden projemizdeki WPF User Control'lerden istediğimizi seçebiliyoruz. Eğer WPF User Control'lerin bir listesi gelmiyorsa hemen projenizi "Build" ederek gerekli listenin yenilenmesini sağlayabilirsiniz.

Artık WPF kontrolümüz Winforms uygulamamızda çalışıyor fakat animasyonumuz daha çalışmıyor. Animasyonumuzun WPF içerisinde Rectangle nesnesine tıklandığında çalışmasını istiyoruz, bunun için aynı ASP.NET uygulamalarında da olduğu gibi hemen WPF User Control'ün arkasındaki (code-behind) koda uzanarak aşağıdaki satırları yazıyoruz.

Partial Public Class UserControl1

    Private Sub rectangle_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles rectangle.MouseLeftButtonDown

        CType(Me.Resources("Storyboard1"), System.Windows.Media.Animation.Storyboard).Begin(Me)

    End Sub

End Class

WPF User Control arkasındaki kod içerisinde Rectangle nesnesinin MouseLeftButtonDown durumunda User Control'e ait kaynaklar içerisinde animasyonumuzu bularak çalıştırıyoruz. Böylece artık Winforms uygulamasında söz konusu dikdörtgene tıklandığında animasyon çalışacaktır.

Winforms'dan WPF içine erişim.

Şimdi ikinci soru geliyor! Peki Winforms penceresinde başka bir kontrol veya kod ile WPF User Control içerisindeki animasyona nasıl ulaşırız? Aslında çok kolay, çünkü özünde bir User Control'den bahsediyoruz. Nesne yönelimli mimari gereği bir şekilde nested nesnelere ulaşabiliyor olmamız gerekir. Mantık olarak yapmamız gereken ilk olarak gidip ElementHost içerisindeki User Control'ü bulmak sonrasında da User Control'ün kaynaklarından istediğimiz animasyonu bularak çalıştırmak. Winforms penceremize klasik bir Button koyduktan sonra yazdığımız kod aşağıdaki şekilde sonlanıyor.

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim UC = CType(ElementHost1.HostContainer.Children.Item(0), UserControl1)

        CType(UC.Resources("Storyboard1"), System.Windows.Media.Animation.Storyboard).Begin(UC)

    End Sub

End Class

Gördüğünüz üzere ElementHost kontrolünün HostContainer yapısı içerisinde WPF User Controlü yakalayabiliyoruz. HostContainer içerisinde şu an zaten tek bir UserControl var, o da bizim UserControl1 olarak yarattığımız WPF User Controlümüz. Gerekli cast'ları da yaptıkran sonra yakaladığımız User Control üzerinden aynı bir önceki adımda olduğu gibi animasyonumuza da ulaşabiliyoruz. Bu şekilde User Control içerisindeki her şeye ulaşabilirsiniz.

WPF User Control'den Winforms'a erişim.

Bir diğer senaryoda da WPF User Control içerisindeki kodlardan dışarıya, yani esas Winforms penceresine ulaşmak isteyebilirsiniz. Aslında bu durumda da eski taktikler işe yarıyor. User Control içerisinde hızlı bir şekilde aşağıdaki gibi bir Property belirleyerek söz konusu User Control'ün yarattığımız Property'sini üst formdan belirliyoruz. Böylece User Control içerisinden dışarıya ulaşabiliyoruz.

Partial Public Class UserControl1

    Private PMyParent As Form

 

    Public Property MyParent() As Form

        Get

            Return PMyParent

        End Get

        Set(ByVal value As Form)

            PMyParent = value

        End Set

    End Property

 

    Private Sub rectangle_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles rectangle.MouseLeftButtonDown

        MyParent.Text = "Tamamdir"

    End Sub

End Class

WPF User Controlümüzün yukarıdaki kodunda MyParent adında bir Property tanımladık. Bu Property'yi doğrudan Winforms penceresinde tanımlarken aslında Winforms penceremizin bir "Instance" ını aktarmış olacağız. böylece User Control doğrudan Winforms penceresinin her şeyine ulaşabilecek. Bizim kodumuzda pencerenin adını değiştiriyoruz :) Şimdi gelelim ana pencerede neler yazacağımız.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim UC = CType(ElementHost1.HostContainer.Children.Item(0), UserControl1)

        UC.MyParent = Me

    End Sub

End Class

Ana pencerenin yüklendiği anda ElementHost içerisine eklenmiş olan UserControl1'i yakalayarak MyParent özelliğini ana pencerenin kendisini aktarıyoruz. Böylece WPF User Control içerisinden de dış pencereye ulaşılabilecek.

Hepinize kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags:
Oca 01

Daha önceki bir yazımda WPF özelliklerini Winforms pencerelerine nasıl taşıyabileceğimizden bahsetmiştim. Oysa bir de tam tersi bir senaryo da mümkün olabilir. Yani Winforms tarafındaki bir kontrolü herhangi bir WPF uygulamasına kullanmak isteyebilirsiniz. Peki bu durumda neler yapabilirz? İşte bu yazımızda bu sorunu çözeceğiz.

Winforms kontrollerini WPF projemize ekleyelim.

İlk olarak yarattığımız herhangi bir WPF projesinde Winforms kontrollerini kullanabilmek için tabi ki System.Windows.Forms namespace'ini projemize referans olarak eklememiz gerekiyor. Ayrıca Winforms kontrolleri ile WPF uygulaması arasında aracı görevi görecek olan WindowsFormsHost sınıfının da projeye kesinlikle referans olarak eklenmesi şart.

WPF projemizde Winforms kontrolleri kullanabilmek için eklediğimiz referanslar.
WPF projemizde Winforms kontrolleri kullanabilmek için eklediğimiz referanslar.

Yukarıdaki ekran görüntüsünde de görebileceğiniz üzere biri .NET Framework 2.0'dan diğeri de 3.0'dan iki farklı harici sınıfı projemize referans olarak eklememiz gerekiyor. Sonrasında artık yazacağımız kodlar ile uygulamamızda Winforms kontrollerini kullanabileceğiz.

Kod ile Winforms kontrollerinin WPF içerisinde kullanımı

Gelin hemen bir örnek deneyelim ve ufak bir WPF uygulaması hazırlayarak içerisine de minik bir animasyon yerleştirelim. Sonrasında hedefimiz bu WPF uygulamasına bir Winforms Button kontrolü yerleştirerek düğmeye basıldığında WPF animasyonunu çalıştırmak olsun.

<Window

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

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

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

  <Window.Resources>

    <Storyboard x:Key="Animasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusX)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusY)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Window.Resources>

  <Grid x:Name="LayoutRoot">

    <Rectangle HorizontalAlignment="Left" Margin="46,80,0,0" VerticalAlignment="Top" Width="199" Height="137" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle"/>

    <Canvas Margin="96,0,295,70" VerticalAlignment="Bottom" Height="118" x:Name="WinformsCanvas"/>

  </Grid>

</Window>

Gördüğünüz gibi kod içerisinde animasyon uygulanan bir dikdörtgen ve bir de Canvas bulunuyor. Söz konusu Canvas'ın adı da WinformsCanvas olarak düzenlenmiş. İşte biz de Winforms kontrolümüzü tam bu Canvas'ın içerisine kod ile ekleyeceğiz.

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

        Dim HostKontrol As New System.Windows.Forms.Integration.WindowsFormsHost

        Dim x As New System.Windows.Forms.Button

        x.Text = "Deneme"

        AddHandler x.Click, AddressOf Tiklandi

        HostKontrol.Child = x

        WinformsCanvas.Children.Add(HostKontrol)

    End Sub

 

    Private Sub Tiklandi(ByVal sender As Object, ByVal e As EventArgs)

        CType(Me.Resources("Animasyon"), Storyboard).Begin(Me)

    End Sub

Gördüğünüz gibi ilk olarak bir WindowsFormsHost kontrolü yaratıyoruz. Bu kontrol herhangi bir Winforms kontrolünün WPF uygulamasına kullanılabilmesini sağlıyor. Biz örnek olarak bir düğme yaratarak HostKontrol değişkenine bunu aktarıyoruz. Son olarak da XAML kodumuzdaki Canvas'ın içerisinde WindowsFormsHost kontrolümü yerleştiriyoruz. Kod içerisinde yarattığımız düğmenin Click durumun da başka bir handler ile yakaladığımız için rahatlıkla istediğimiz WPF animasyonunu yakalayarak çalıştırabiliriz. Tabi hikaye sadece standart Winforms kontrolleri için geçerli değil, isterseniz Winforms uygulamalarında UserControl'lerinizi de aynı şekilde kullanabilirsiniz.

XAML ile Winforms kontrollerinin WPF içerisinde kullanımı

Peki doğrudan XAML içerisinde Winforms kontrollerini kullanmak istersek neler yapabiliriz? Böyle bir durumda da doğrudan XAML içerisinde söz konusu sınıfları tanımlamış olmanız gerekecektir.

  xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

  xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

Yukarıdaki gibi gerekli tanımlamaları yaptıktan sonra artık ister doğrudan WindowsFormsHost kontrolünü ister herhangi bir Winforms kontrolünü XAML içerisinde rahatlıkla kullanabilirsiniz.

<Window

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

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

  xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"

  xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"

  x:Class="Window1"

  x:Name="Window"

  Title="Window1"

  Width="640" Height="480">

  <Window.Resources>

    <Storyboard x:Key="Animasyon">

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusX)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Rectangle.RadiusY)">

        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>

        <SplineDoubleKeyFrame KeyTime="00:00:01" Value="99"/>

        <SplineDoubleKeyFrame KeyTime="00:00:02" Value="0"/>

      </DoubleAnimationUsingKeyFrames>

    </Storyboard>

  </Window.Resources>

  <Window.Triggers>

  </Window.Triggers>

 

  <Grid x:Name="LayoutRoot">

    <Rectangle HorizontalAlignment="Left" Margin="46,80,0,0" VerticalAlignment="Top" Width="199" Height="137" Fill="#FFFF0000" Stroke="#FF000000" x:Name="rectangle"/>

    <Canvas Margin="96,0,295,70" VerticalAlignment="Bottom" Height="118" x:Name="WinformsCanvas">

    <WindowsFormsHost>

      <wf:Button Text="Tikla" Click="Tiklandi"/>

    </WindowsFormsHost>

    </Canvas>

  </Grid>

</Window>

Düğmemizin code-behind kısmına baktığımızda aslında standart bir event-handler'dan farklı birşey de görmüyoruz.

    Private Sub Tiklandi(ByVal sender As Object, ByVal e As EventArgs)

        CType(Me.Resources("Animasyon"), Storyboard).Begin(Me)

    End Sub

Böylece Winforms kontrolümüzü WPF içerisinde rahatlıkla kullanabiliyoruz. Özellikle WPF kontrolleri arasında şu an eksik olan çoğu Winforms kontrolünü bu şekilde WPF dünyasına alarak söz konusu kontrollerin işlevselliklerinden faydalanabiliriz.

Hepinize kolay gelsin.

Kaynak

Daron Yöndem

http://daron.yondem.com

Tags: