WPF, Windows Phone Command Binding Event Handling

WPF ve Windows Phone’da Command Binding İşlemiyle Event Handling

Aşağıdaki uygulama Windows Phone için yazılmıştır. Windows Phone, WPF/Silverlight altyapısı üzerine geliştirilmiş olduğu örnekte kullanılan bu özellik WPF ile geliştirilen masaüstü veya Silverlight ile geliştirilen web uygulamalarında da kullanılabilir.

NOT : Bu yazı Aykut TAŞDELEN’in C++ Java ve C# ile UML ve Dizayn Paternleri kitabından alıntıdır izinsiz kullanılıp alıntı yapılamaz ! Konunun devamı söz konusu kitapta yer almaktadır.

WPF’te event handling konusuna command patern’i bağlamında yeni bir boyut getirilmiştir. System.Windows.Input.ICommand interface’i ile command patern’i uygulanarak event handling işlemi gerçekleştirilebilir.

public interface ICommand

{

event EventHandler CanExecuteChanged;

bool CanExecute(object parameter);

void Execute(object parameter);

}

Command nesneleri bir eyleme ilişkin lojiği enkapsüle eder. Böylece uygulamanın çeşitli unsurları bir eylemi gerçekleştirmek istediğinde bunu ilgili command nesnesi yoluyla yapabilir. Aşağıdaki örnekte ICommand interface’inin gerçekleştirimi olan TestCommand sınıfı görülmektedir.

namespace WPhoneCommandBinding

{

public class TestCommand : System.Windows.Input.ICommand

{

public bool CanExecute(object parameter)

{

return true;

}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)

{

MessageBox.Show(“Test : ” + parameter);

CanExecuteChanged(this, new EventArgs());

}

}

}

Bu sınıfın Execute() metodu parametresine gönderilen bilgiyi mesaj kutusu içinde göstermektedir. Ancak bu sınıfa ait bir nesnenin kullanımı ve Execute() metoduna parametre gönderilişi oldukça ilginçtir zira XAML içerisinden dekleratif şekilde yapılmaktadır.

<phone:PhoneApplicationPage

xmlns:tst=”clr-namespace:WPhoneCommandBinding”>

<StackPanel>

<StackPanel.Resources>

<tst:TestCommand x:Key=”komut” />

</StackPanel.Resources>

<Button
Command=”{StaticResource komut}”
CommandParameter=”Deneme123″
Name=”btnTest” Content=”Test” />

</StackPanel>

</phone:PhoneApplicationPage>

XAML kodu incelenirse öncelikle WPhoneCommandBinding namespace’inin tst kısaltmasıyla tanımlandığı daha sonra buradaki TestCommand türünde komut isimli bir kaynak tanımlanıp bu kaynağın da daha sonra Button’un Command property’sine bind edilerek kullanıldığı görülmektedir. Örnek emülatörde çalışırılıp denendiğinde ise ekrana gelen mesaj kutusu içerisinde “Deneme123” metninin sunulduğu görülecektir.

Reklamlar

WPF Cross Thread Operasyonlar

WPF ve Forms kütüphanelerinde programatik olarak açılmış farklı bir thread’ten main thread içerisinde yaratılmış olan gui nesnelerini kullanmak exception’a neden olur. Sözgelimi bir butona basıldığında çalışan bir döngüye ait değişkenin değeri bir label’a yazdırılmak istenirse ;

Okumaya devam et

XAML Editörleri

WPF ya da Silverligth’la uğraşan programcılar Visual Studio’nun XAML editörünü genelde beğenmez ve farklı editör arayışına girer. Şüphesiz Expression Blend iyi bir editör ancak farklı alternatifleri de yok değil. Örneğin XAMLPAD, SDK içinden çıkan basit ama güzel bir editör ya da KAXAML bir 3. parti editör olarak tavsiye edilebilir.

Ücretsiz Free SP Generator , Dinamo Çıktı !

C ve Sistem Programcıları Derneği eğitmenlerinden Aykut TAŞDELEN’in geliştirdiği ücretsiz bir araç olan DinamoSPGenerator çıktı.
SQL Server üzerinde uygulama geliştirenlerin sıkça yaşadığı bir sorun olan CRUD işlemlerinden sorumlu stored procedure’leri elle yazmaya bu araç sayesinde ihtiyaç kalmıyor. Bu aracı aşağıdaki adresten sıkıştırılmış bir dosya biçiminde indirip açmanız ve içinden çıkan setup.exe’yi çalıştırmanız yeterli. Start menüsünde “CSD” isimli bir klasör içinde oluşacak olan kısayoldan uygulamanızı çalıştırabilirsiniz.

Dikkat : 18 Kasım 2010 itibariyle uygulamanın eski versiyonu zaman aşımına uğramaktadır Bu nedenle kullanmaya devam etmek isteyenler aşağıdaki download linkinden yeni versiyonu indirip yine ücretsiz kullanmaya devam edebilirler.

http://www.aykuttasdelen.net/downloads/Dinamo_SPGenerator_Kurulum.zip

Bir sihirbaz mantığıyla yazılmış olan bu araçta kullanılan teknoloji; WPF (Windows Prensentation Foundation). Ayrıca çok kısa bir zaman içinde bu aracın Visual Studio ile entegre çalışan bir eklenti add-on biçimi de kullanıma açılacak.

C ve Sistem Programcıları Derneğinde vermekte olduğum eğitimlerde öğrenci arkadaşlara bir örnek teşkil edebilmesi için yazdığım bu uygulamayı diğer yazılımcı dostlarımla da paylaşmak istedim. Amacım öğrencilerimi hazır yazılmış 3. parti araçlar veya bileşenler kullanmak yerine bilinç düzeylerini arttıracak, arka planında (kendileri geliştirdiği için) ne olup bittiğini bildikleri yapıları kullanmaya teşvik etmek. Diğer  klişe eğitim kurumlarından farklı bir vizyonla kendi derleyicimizi kendi işletim sistemimizi yazmak ve bunu da diğer meslektaşlarımızla paylaşmak vizyonumuzun bir projeksiyonu. Benzer şekilde bundan sonraki ASP.NET eğitimlerinde IIS’e alternatif basit bir web sunucu ile tarayıcı geliştirmek ve onları kullanmak cihetine gideceğiz.

WPF Windows Presentation Foundation

WPF Windows Presentation Foundation Kitabı Çıktı

Uzun bir süredir üzerinde çalışmakta olduğum WPF Windows Presentation Foundation kitabım pusula yayıncılıktan çıktı. Okurlarım Türkçe kullanımına ne kadar dikkat ettiğimi bilirler, bu kitapta da öğretici, sade ve düzgün bir dil kullandım. Çünkü internetteki yazılarda hep eleştiregeldiğim VJ ağzıyla yazılmış bozuk Türkçeli yazılara çok kızıyorum. Hep kızdığım bir şey de; bu maalesef kitaplarda da yapılıyor ele alınan konuya hayran kalmış onu öve öve bitiremeyen yazar klişesi. Ben konuyu şövenist bir tutumla anlatmak yerine eleştiriler de yaparak, zaman zaman API,MFC, Swing ya da QT gibi farklı teknolojilerle karşılaştırarak, benzerliklerine dikkat çekerek ele aldım. Herşeyden önemlisi C ve Sistem Programcıları Derneğinin genel çizgisi ve tarzında yani bir sistem programcısının bakış açısıyla WPF’i inceledim. Özellikle bazı bölümlerde bu durum dikkatinizi çekecektir. Ayrıca kitapta XAML, MVC, WCF (Windows Communication Foundation) ve Blend ile ilgili de başlıklar bulacaksınız. Kitapta ele alınan başlıklar ise şöyle;
•             MVC ve MVVM Patern’lerinin kullanımı
•             XAML kullanımı
•             Paneller ve Diğer Nesneler
•             Routed Event ve Komutlar
•             WPF’te Kaynak Kullanımı
•             WPF’te DataBinding işlemleri
•             XBAP, BAML vb kavramlar
•             WPF ile animasyon uygulamaları
•             Çizim işlemleri
•             WPF’te Win32 mesajlarının yakalanması
•             WPF MultiThread Programlama
•             WPF’te Tema ve stil uygulamaları
•             WCF kullanımı
•             .NET Framework 4.0 Eklentileri
•             Expression Blend’in Kullanımı
•             Ve diğerleri .

Kitap temini, WPF ve Silverlight eğitimleri için info@aykuttasdelen.net adresinden yazara ulaşabilirsiniz…

WPF MVC Patern’i Nedir

WPF ‘te MVC (Model View Controller) Patern’i Nasıl Kullanılır ?

Not : Bu yazı Aykut TAŞDELEN’in WPF kitabından alıntıdır izinsiz kullanımı suçtur ! Konuyla ilgili diğer kısımlar kitapta yer almaktadır.

MVC (Model-View-Controller) patern’inin kısaca ne olduğunu anlatmak, hatta kabaca bir tanım getirmek gerekirse;

  • Model nitelemesi; uygulamanın üzerinde çalıştığı verileri,
  • View; model’in sunumunu,
  • Controller ise; klavye, mouse, stylus gibi sistem girdilerinin ve bunlara ilişkin event’lerin yönetimini ifade etmektedir.

Gevşek bağlı modüllerden oluşan böylesi bir sistemin esası; parçalar arasındaki doğrudan referans’ları azaltmaktır. Yapılması gereken şey; parçalar arasında interface’ler veya soyut sınıflar kullanılarak (dependency injection ve object mocking diye bilinen kavramlar) gevşek bağlar oluşturulmasıdır.

MVC’nin WPF’teki İmplementasyonu

WPF’te MVC patern’i implemente edilirken şu dört  temel WPF özelliğinden faydalanılır. Bu özelliklerin tümü, MVC’ye ilişkin Model-View-Controller kısımlarının birbirlerine loosely coupled yani gevşek bağlı olmasını sağlar.

  1. Rotalanmış Komutlar (Routed Commands)
  2. Veri Bağlama (Data Binding)
  3. Collection View
  4. Kaynak (Resource) kullanımı

Örnek : Aşağıdaki uygulamada MVC patern’inin nasıl kullanılabileceği gösterilmektedir. Senaryo kısaca şöyledir :

Model kısmında yer alan CStok sınıfı ve bu sınıf türündeki nesneleri bir kolleksiyon olarak barındıran StokCollection uygulamanın üzerinde çalıştığı verileri ifade eder. Amaç bu kolleksiyonun elemanlarının bir ListBox’ta gösterilmesidir. Ancak listeleme gibi görevleri (aksiyonları) işleyen bir de Controller isimli sınıf söz konusudur.

MVC’ye ilişkin temek unsurlar ve bu unsurları temsil eden sınıflar ekran çıktısında da görüldüğü gibi ayrı ayrı klasörlere alınmıştır. Şüphesiz gerçek hayatta bu sınıfların ayrı ayrı dll’lerin içinde yer almaları tercih edilmelidir.

 

Şekil 11.3 :Uygulamanın temel yapıları

Model Kısmı

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Collections.ObjectModel;

namespace WPF_MVC.Model

{

    public class CStok : INotifyPropertyChanged

    {

        private int m_StokID;

        public int StokID

        {

            get { return m_StokID; }

            set { m_StokID = value; }

        }

        private int m_Adet;

        public int Adet

        {

            get { return m_Adet; }

            set

            {

                m_Adet = value;

                OnChanged(“Adet”);

            }

        }

        private string m_Urun;

        public string Urun

        {

            get { return m_Urun; }

            set

            {

                m_Urun = value;

                OnChanged(“Urun”);

            }

        }

public CStok(int StokID, string urun, int adet)

        {

            m_StokID = StokID; 

            m_Adet = adet;

            m_Urun = urun;

        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnChanged(string prop_name)

        {

            if (this.PropertyChanged != null)

            {

                PropertyChanged(this,
                   new PropertyChangedEventArgs(prop_name));

            }

        }

    }

    //////////////////////////////////////////////////////////
 

    public class StokCollection : ObservableCollection<CStok>

    {

        public static StokCollection Yukle()

        {

            StokCollection stoklar = new StokCollection();

            stoklar.Add(new CStok(1, “CD-ROM”, 200));

            stoklar.Add(new CStok(2, “Mouse”, 10));

            stoklar.Add(new CStok(3, “Pinter”, 23));

            return stoklar;

        }

    }

}

View Kısmı

StokEkrani.xaml
<Window x:Class=”WPF_MVC.StokEkrani”

    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8221;

    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml&#8221;

    Title=”StokEkrani” Height=”300″ Width=”300″>

    <Grid>

        <ListBox Margin=”12,11,12,45″ Name=”lstStoklar” />

        <Button Height=”26″ Margin=”14,0,10,10″ Name=”btnListele”
                VerticalAlignment=”Bottom”
                Click=”btnListele_Click”>Listele</Button>

    </Grid>
</Window>

——————————————————

StokEkrani.xaml.cs

using WPF_MVC.Controller;

using WPF_MVC.Model;

namespace WPF_MVC

{

    public partial class StokEkrani : Window

    {

        private StokController controller;

        public StokEkrani()

        {

            InitializeComponent();

            controller = new StokController(this, StokCollection.Yukle ()); 

        }

        private void btnListele_Click(object sender, RoutedEventArgs e)

        {

            controller.Listele(); 

        }

    }

}

Controller Kısmı

Controller.cs

using System;

using System.Collections.Generic;

using System.Windows;

using System.Text;

using WPF_MVC.Model;

using System.Windows.Controls;

using System.Windows.Data;

namespace WPF_MVC.Controller

{

    public interface IController

    {

        void Listele();

        // …

    }

    public class StokController : IController

    {

        private StokCollection m_stoklar;  // Model

        private StokEkrani m_Wnd;          // View  

        public StokController(StokEkrani wnd, StokCollection stoklar)

        {

            m_Wnd = wnd;

            m_stoklar = stoklar;

        }

        #region IController Members

        public void Listele()

        {

            ListBox lst = (ListBox) m_Wnd.FindName(“lstStoklar”);

            lst.DisplayMemberPath = “Urun”;

            lst.ItemsSource = m_stoklar;

            lst.IsSynchronizedWithCurrentItem = true; 

        }

        #endregion

    }

}

Şüphesiz gerçek hayatta beklentiler uygulama yapısının daha karmaşık olmasını gerektirir. Ancak burada amaç; kılavuz olabilecek anlaşılırlığa sahip, basit bir örnek vermektir.

XAML Üzerinde Programatik İşlemler

Not : Bu yazı Aykut TAŞDELEN’in WPF kitabından alıntıdır izinsiz kullanımı suçtur ! Konuyla ilgili diğer kısımlar kitapta yer almaktadır.

XAML kodları ve dosyaları üzerinde programatik okuma ve yazma işlemleri gerçekleştirilebilir. System.Windows.Markup namespace’indeki XamlReader ve XamlWriter sınıfları bu işlemler için özelleşmiştir.

XamlReader sınıfına ilişkin Load() ve LoadAsync() metotları senkon ve asenkron biçimde xaml içeriğini uygun bir WPF nesnesine yüklemeye yarar.  Örneğin aşağıdaki kod, bir string değişkende tutulmakta olan xaml içeriğinin (bu bir .xaml dosyasından okunarak elde edilmiş de olabilirdi) Canvas nesnesine yüklenmesini ve bu içerikte bulunan btnTest isimli düğmenin FindName() ile bulunarak content’inin değiştirilmesini örneklemektedir.

string xmal = @”<Canvas Width=’400′ Height=’350′ xmlns=’http://schemas.microsoft.com/winfx/2006/xaml/presentation&#8217; xmlns:sys=’clr-namespace:System;assembly=mscorlib’ xmlns:x=’http://schemas.microsoft.com/winfx/2006/xaml’&gt;

<Rectangle Height = ‘100’ Canvas.Left = ‘100’ Canvas.Top=’100′ Fill=’Gray’>

<Rectangle.Width>

100

</Rectangle.Width>

</Rectangle>

<Polygon Stroke=’Blue’ Points=’0, 0 100, 100 50, 30′>

</Polygon>

<Button Name=’btnTest’ Width=’100′ Height=’30’ Canvas.Top=’50’ Canvas.Left=’60’> Okay </Button>

<ListBox Width=’200′ Height=’300′ Canvas.Left=’170′ Canvas.Top=’50’>

<Rectangle Width=’50’ Height=’15’ Fill=’Navy’>

</Rectangle>

<ListBoxItem> 200 </ListBoxItem>

<ListBoxItem> 300 </ListBoxItem>

</ListBox>

</Canvas>

“;

 

Canvas canvas = (Canvas) XamlReader.Load(
                new XmlTextReader(new StringReader(xmal)));

 

this.Content = canvas;

Button button = (Button) canvas.FindName(“btnTest”);

button.Content = “Test”;

 

Aşağıdaki örnekteyse bir Button nesnesinin Save() ile XAML’e kaydedilişi ve sonra tekrar yüklenişi gösterilmiştir :

Button btn = new Button();

btn.Height = 40;

btn.Width = 80;

btn.Background = Brushes.Azure;

btn.Content = “Deneme”;

 

// Kaydet

string strBtn = XamlWriter.Save(btn);

 

// Yükle

StringReader stringReader = new StringReader(strBtn);

XmlReader xmlReader = XmlReader.Create(stringReader);

Button btn2 = (Button)XamlReader.Load(xmlReader);

 

this.Content = btn2;