Makale Özeti

Bu yazımızda WPF ve .Net 4.0 yardımı ile basit bir Worflow Designer oluşturmak için yapılması gereken adımları incelemeye çalışıyoruz.

Makale

Windows Workflow Foundation (WF) ile incelemelerimizi bir süredir .Net 3.0 kütüphanesi ve Visual Studio IDE 'si üzerinde alışık olduğumuz tasarım ekranı ile incelemeye ve uygulamalarımızı geliştirmeye çalışıyorduk. Ancak çok yakın bir zaman içerisinde .Net 4.0 'ın final sürümüne kavuşacağını düşünerek bu yazımızı Visual Studio 2010 IDE sinde .Net 4.0 ile Worklow Designer programlama modelini incelemeye çalışıyor olacağız.

Not: Worfklow Foundation 4.0 ile ilgili detaylı bilgi için Burak Selim Şenyurt 'un yazmış olduğu bu güzel yazıyı incelemenizi tavsiye ediyorum. Çünkü bu yazımızda uygulama bazında WF 4.0 'ı inceliyor olacağız.

Yakın zaman içerisinde karşımıza çıkacak olan Visual Studio 2010 bilindiği üzere WPF ile yeniden tasarlandı. Daha esnek ve daha kullanışlı bir tasarım ile karşımıza çıktı. Özellikle WPF 'in esnekliğini Visual Studio 2010 üzerinde kullanabileceğimize hiç şüphemiz yoktur. VS2010 'da bu değişiklikler olurken bir yandan da yenilenen görünümü, tasarım yapısı ve WPF ile hazırlanmış iş akışlarını tasarlayabildiğimiz Activity Library ekranı yardımı ile biz geliştiriciler için kullanım kolaylaşmıştır.

Bu kadar yenilenen tasarımdan bahsettikten sonra artık uygulama geliştirmeye geliştirmeye başlayabiliriz. Yazımızında başında da bahsettiğimiz gibi uygulamalarımızı VS2010 ve .Net 4.0 ile geliştiriyor olacağız. Uygulamamız esnasında bir WPF uygulamasında iş akışı süreçlerini kullanıyor olacağız.

İlk olarak VS2010 yardımı ile WPF uygulaması oluşturuyoruz.



Projemiz başarılı bir şekilde oluşturulduktan sonra proje özellikleri ekranında yapacak olduğumuz ufak birkaç işlem bulunmaktadır. Projelerde varsayılan target Framework .Net Framework 4 Client Profile seçeneği seçili olarak gelmektedir. Biz bunu .Net Framework 4 seçeneği seçili olacak şekilde değiştiriyoruz.



Bu ekranda yapmış olduğumuz değişiklik esnasında karşımıza Target Framework 'u değiştirmek istiyor musunuz? şekilde soru soran bir ekran çıkacaktır. Evet dedikten sonra artık .Net Framework 4 'ün bütün nimetlerinde faydalanır duruma geliyoruz.

Peki biz bu değişikliği neden yaptık. Çünkü belirli bir şablon tipine dahil olan bir proje yi oluşturduğumuzda yalnızca bu proje tipinde kullanılabilecek isim alanlarının ve araçlarının olduğu daha özelleştirilmiş bir framework bizlere sunulmaktadır. Sebebi ise o proje geliştirilirken onun ile ilgisi olmayan framework kısımlarını kullanmamaktır. Bunun en büyük faydası ile Garbage collector 'un daha rahat çalışması ve çabuk derleme şeklinde yorumlayabiliriz. Ancak biz bu yazımızda WF tasarım ekranını kendimiz oluşturmaya çalışacağımız için framework 'un tamamına ihtiyacamız olacaktır. Çünkü biraz önceki kısıtlı framework 'te WF geliştirmemize olanak tanıyacak olan dll 'ler yer almamaktaydı. Bu kısa bilgiyi de öğrendikten sonra işlemlerimizi yapmaya devam edebiliriz.

Şimdi uygulamamıza bir tane Class Library ekliyoruz. Sonrasında bir adet sınıf oluşturuyoruz ve bu sınıfı CodeActivity 'den türetiyoruz. Sonrasında ise aşağıdaki kodları ekliyoruz.

namespace CustomActivities
{
    using System;
    using System.Activities;
    using System.Activities.Statements;

    public class Prompt : CodeActivity
    {
        public string Text { get; set; }
        public string Response { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
           throw new NotImplementedException();
        }

         public static Activity GetSimpleSequence()
         {
             return new Sequence
             {
                 Activities =
                 {
                     new Prompt(),
                     new Assign()
                 }
             };
        }
    }
}

Bu işlem sonrasında projeyi derliyor ve oluşturmuş olduğumuz WPF uygulamasına Add Reference ekranında projeler kısmından ekliyoruz.



Sonrasında WPF uygulamasına referans eklemeye devam ediyoruz. CodeActivity 'yi kullandığımız için projemizde System.Activities, System.Activities.Core.Presentation, System.Activities.Presentation DLL 'lerinin projeye ekli olması gerekmektedir.



Bu işlemi de tamamladıktan sonra hazırlayacak olduğumuz Workflow Designer 'i oluşturmaya başlayabiliriz.

WPF uygulaması içerisinde yer alan MainWindows.xaml üzerinde işlemler yapağız. Oluşturacak Workflow Designer 'ı WPF Grid içerisinde düzenliyor olacağız. Yaptığımız işlem sonrasında ise WorkflowDesigner 'ın içerisine Sequence aktivitenin tasarım ekranında yer alacaktır.

Şimdi tasarım ekranı üzerinde birkaç düzenleme yapalım. İlk olarak standart olması açısından tasarım ekranının boyutlarını 800x600 olarak belirliyoruz.



Biz bu işlemleri yaparken IDE 'nin yaptığımız değişiklikleri XAML kod üzerine yansıttığını unutmayalım. Yani istersek bu işlemlerin hepsinin XAML üzerinde nesnelerin özelliklerine değerler vererekte yapabilmemiz mümkündür.

Tasarım ekranı üzerinde yapmış olduğumuz işlemler sonrasında şimdi de Grid 'i özelleştireceğiz. ColumnDefinitions özelliklerine CollectionEditor yardımı ile birkaç kolon ekleyip özelliklerine değerler atayacağız.



Collection Editor 'u açtıktan sonra 3 tane kolon ekliyoruz.



Kolonları ekledik. Ancak genişlik boyutunu gördüğünüz kadarıyla 4* şeklindedir. Peki bu yıldız nedir? Kısaca açıklayalım.

Yıldız değeri kullanılan satır ya da sütunlar değişebilir şekilde kullanılabilir. Örneğin * olan değerler ilk durumda satır ve sütünlar bir kez kullanılabilirken 2* olanlar iki kez kullanılabilmektedir.

Grid üzerinde yapmış olduğumuz değişiklikler XAML kod tarafına nasıl yansıdığına kısaca göz atmak gerekirse şu şekilde olmuştur.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition Width="4*" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
</Grid>

Herşey güzel. Bu grid üzerine neden 3 kolon koyduk? Hemen açıklayalım. Visual Studio IDE 'sinden referans alarak ve kendi çapımızda bir Workflow ekranı yaptığımızı düşünürsek, sol tarafta ToolBox (araç kutusu) orta tarafta Workflow Designer (İş akışı tasarım) en sağ tarafta da Property Inspector (özellikler( bölümü yer alacaktır.

XAML tarafındaki işlemleri şimdilik tamamladık. Sırada kod tarafında yapacağımız işlemler var. Bunun için MainWindows.xaml 'in kod ekranını açarak işlemlerimize başlıyoruz.

İlk olarak kullanacak olduğumuz isim alanlarını ekliyor olacağız.

using System.Activities.Core.Presentation;
using System.Activities.Presentation;
using System.Activities.Presentation.Toolbox;
using System.Activities.Statements;

Kullanacak olduğumuz isim alanları hazır durumdadır. Bir Workflow Designer yaptığımıza göre WorkflowDesigner sınıfını proje içerisinde kullanıyor olamak gerekiyor.

public partial class MainWindow : Window
{
    private WorkflowDesigner wd;

    public MainWindow()
    {
        InitializeComponent();
    }
}

Şimdi ise Ekran üzerinde WorkflowDesigner oluşturabilmek için AddDesigner isimli private bir metot oluşturacağız. Bunun yardımı ile iş akışı tasarım ekranının oluşmasını ve grid 'in hangi kısmında duracağını belirtiyor olacağız.

private void AddDesigner()
{
    //WorkflowDesigner sınıfı çağırılır.
    this.wd = new WorkflowDesigner();

    //Workflow Designer 'in ekran üzerinde nerede olacağını belirtiyoruz.
    Grid.SetColumn(this.wd.View, 1);

    //Varsayılan olarak bir Sequence oluşturuyour.
    this.wd.Load(new Sequence());

    //WorkflowDesigner 'i grid 'e ekliyoruz.
    grid1.Children.Add(this.wd.View);
}

Çağırmış olduğumuz Sequence sınıfının DesignerMetaData() sınıfını içinde barındıran bir sınıf ile kayıt etmemiz gerekmektedir. Bu sebeple RegisterMetaData() isimli bir metot daha oluşturarak bu işlemi gerçekleştiriyor olalım.

//Sequence sınıfının kaydı yapılıyor.
private void RegisterMetaData()
{
    (new DesignerMetadata()).Register();
}

Sırada yapacak olduğumuz işlem ise MainWindow ekranı oluşturulurken hazırlamış olduğumuz metotları çağırmak olacaktır.

public MainWindow()
{
    InitializeComponent();
    this.AddDesigner();
     this.RegisterMetaData();

}

Çağırma işlemleri de tamamlandıktan sonra artık workflow tasarım ekranımızın ilk adımınının nasıl olduğuna göz atabiliriz. Bunun için projeyi çalıştırmak yeterli olacaktır.



İstediğimizi başardık. Artık WPF uygulamasını bir iş akışı tasarımcısı yapma konusunda ilk adımımızı attık ve tasarım bölümünü oluşturduk. Sırada yapacak olduğuğumuz işlem ise ToolBox 'ı ve Property Inspector 'u oluşturmak olacaktır.

Oluşturacak olduğumuz bu iki bölümü yaparken Workflow Designer 'ı oluşturduğumuz gibi basit bir şekilde olacaktır. Çünkü .net 4.0 'ın yapısı bize daha da fazla şekilde esnek, geliştirilebilir ve genişletirilebilir bir yapı sunmaktadır.

WPF Grid içerisine ToolBox 'ı oluşturma işlemine başlıyoruz. Bu işlem için GetToolboxControl isminde bir metot kullanırken bunu ToolboxControl den oluşturuyor olacağız.

Toolbox Category Item Collection 'nun içerisine iki değer atayacağız. Bunlar;
1. CustomActivitiex.Prompt aktivitesi,
2. System.Activities.Statements.Sequence aktivitesi olacaktır.

private ToolboxControl GetToolboxControl()
{
    // Toolbox kontrol oluşturuluyor.
    ToolboxControl ctrl = new ToolboxControl();

    //Kategorideki elemanlar için koleksiyon oluşuturuluyor.
    ToolboxCategory categoryItems = new ToolboxCategory("category1");

    //Toolbox öğeleri oluşturulur.
    ToolboxItemWrapper tool = new ToolboxItemWrapper("CustomActivities.Prompt",     "CustomActivities", null, null);

    ToolboxItemWrapper tool2 = new ToolboxItemWrapper("System.Activities.Statements.Sequence",
"System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", null, "Sequence");

    // Toolbox öğeleri kategoriye ekleniyor.
    categoryItems.Add(tool);
    categoryItems.Add(tool2);

    //kategoriye eklenen toolbox kontrolleri.
    ctrl.Categories.Add(categoryItems);

    return ctrl;
}

Toolbox kontrol 'ün içeriğini kontrolduğumuza göre şimdi de toolbox 'ı eklemek için AddToolBox() isimli metodu oluşturuyor.

private void AddToolBox()
{
    ToolboxControl tc = GetToolboxControl();
    Grid.SetColumn(tc, 0);
    grid1.Children.Add(tc);
}

SSon olarak bu metodu mainwindow metodunda çağırdıktan sonra uygulamamızı derleyerek oluşan sonuca bir göz atıyoruz.



İş akışı tasarım ekranı oluşturulması adımları olan Toolbox ve Workflow Designer bölümlerinin oluşturulmasını başarılı bir şekilde tamamlamış bulunuyoruz. Son adımımız olan Property Inspector bölümünün eklenmesi aşamasını şimdi yapıyor olalım.

Property Inspector ekranını kullanmak için her zamanki gibi eklememize yarayan bir metot oluşturacağız. Sonrasında ise bu metodu formun oluştuğu anda çağırarak işlemlerimizi tamamlıyor olacağız.

Şu ana kadar yapmış olduğumuz işlemler esnasında gördüğümüz kadarıyla aslında temek bir iş akışı tasarım ekranı oluşturmak oldukça kolaylaştırılmıştır. Özellikler ekranını hazırlarken de bu kolaylıklardan yararlanarak basitçe işlemlerimizi tamamlıyor olacağız. WorkflowDesigner sınıfının UIElement lerinden olan PropertyInspectorView yardımı ile özellikler ekranını rahatlıkla ekleyeceğiz.

private void AddPropertyInspector()
{
   Grid.SetColumn(wd.PropertyInspectorView, 2);
   grid1.Children.Add(wd.PropertyInspectorView);
}

Property Inspector ekranını da eklediğimize göre artık uygulamamızın en son haline bakabiliriz.



Sonuç tam istediğimiz gibi gözükmektedir.

Şu ana kadar yazmış olduğumuz kod parçalarının birleştirilmiş hallerine göz atmak gerekirse sonuç aşağıdaki gibi olacaktır.

using System.Windows;

using System.Activities.Core.Presentation;
using System.Activities.Presentation;
using System.Activities.Presentation.Toolbox;
using System.Activities.Statements;
using System.Windows.Controls;

namespace HostApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
    public partial class MainWindow : Window
    {
        private WorkflowDesigner wd;

        public MainWindow()
        {
            InitializeComponent();
            this.AddDesigner();
            this.RegisterMetaData();
            this.AddToolBox();
            this.AddPropertyInspector();
        }

        private void AddDesigner()
        {
             //WorkflowDesigner sınıfı çağırılır.
             this.wd = new WorkflowDesigner();

             //Workflow Designer 'in ekran üzerinde nerede olacağını belirtiyoruz.
             Grid.SetColumn(this.wd.View, 1);

             //Varsayılan olarak bir Sequence oluşturuyour.
             this.wd.Load(new Sequence());

             //WorkflowDesigner 'i grid 'e ekliyoruz.
             grid1.Children.Add(this.wd.View);
        }

        //Sequence sınıfının kaydı yapılıyor.
        private void RegisterMetaData()
        {
            (new DesignerMetadata()).Register();
        }

        //Toolbox oluşturuluyor.
        private ToolboxControl GetToolboxControl()
        {
            // Toolbox kontrol oluşturuluyor.
            ToolboxControl ctrl = new ToolboxControl();

            //Kategorideki elemanlar için koleksiyon oluşuturuluyor.
            ToolboxCategory categoryItems = new ToolboxCategory("category1");

            //Toolbox öğeleri oluşturulur.
            ToolboxItemWrapper tool = new ToolboxItemWrapper("CustomActivities.Prompt", "CustomActivities", null, null);

             ToolboxItemWrapper tool2 = new ToolboxItemWrapper("System.Activities.Statements.Sequence",
                  "System.Activities, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", null, "Sequence");

             // Toolbox öğeleri kategoriye ekleniyor.
             categoryItems.Add(tool);
             categoryItems.Add(tool2);

            //kategoriye eklenen toolbox kontrolleri.
            ctrl.Categories.Add(categoryItems);
            return ctrl;
       }

       //Ekrana toolbox bölümü eklendi.
       private void AddToolBox()
       {
            ToolboxControl tc = GetToolboxControl();
            Grid.SetColumn(tc, 0);
            grid1.Children.Add(tc);
       }

       //Özellikler (Property Inspector) bölümü ekleniyor.
       private void AddPropertyInspector()
       {
             Grid.SetColumn(wd.PropertyInspectorView, 2);
             grid1.Children.Add(wd.PropertyInspectorView);
        }
    }
}

Sonuç olarak .Net Framework 'un ve WPF 'in esnekliğinden yararlanarak çok hızlı bir şekilde iş akışı tasarım ekranının başlangıç düzeyini oluşturmuş bulunuyoruz. Bu yazımızı takiben aynı uygulama üzerinden geliştirmelerimize devam ederken CustomActivity kütüphanesini daha aktif kullanarak harici aktiviteler oluşturuyor olacağız.

Umarım yararlı olabilmiştir.

Turhal Temizer

info@turhaltemizer.com
http://turhal.blogspot.com