• Anasayfa
  • Hakkımızda
  • Etkinlikler
  • Destek Verin
  • Site Haritası
  • Giriş Yap
  • Üye Ol
  • Facebook
  • Twitter
  • RSS
Yazılım Dilleri
  • Soru - Cevap
  • EĞİTİM SETİ
  • KATEGORİ
  • DUYURU
  • TEKNOLOJİ HABERLERİ

Son Sorular

  • 23.04.2016 00:55:33C programlama 2 oyun
  • 20.04.2016 16:34:41Local Database
  • 15.04.2016 14:26:15Fatura kayıt işlemi
  • 21.03.2016 01:55:30C# problem

Popüler Sorular

  • 27.05.2012 05:49:50Asp.Net ile Date time alana veri ekleyemiiyorum ?
  • 2.04.2012 00:45:18.exe uzantılı dosya için dijital imza nerde nasıl alınır.
  • 12.05.2012 08:44:49Acil Yardım
  • 27.05.2012 13:46:51veri tabanı bağlantısı
  • .Net Framework
  • 8085 Assembly
  • Active Directory
  • ADO.NET
  • Android
  • Apple IOS
  • Arduino
  • ASP.NET
  • ASP.NET MVC
  • Blackberry
  • C#.Net
  • C++
  • CCG Framework
  • CISCO
  • CSS
  • Diğer
  • Dreamweaver
  • Entity Framework
  • Exchange Server
  • Gömülü Sistemler
  • GSM Programlama
  • Güncel
  • Güvenlik
  • HTML5
  • Java
  • Javascript / JQuery
  • Jira
  • Kariyer ve İş Yaşamı
  • LINQ
  • LibreOffice
  • Linux
  • Matlab
  • Microsoft Dynamics CRM
  • Mobil Uygulama Geliştirme
  • MySQL
  • NoSQL
  • Oracle
  • OWIN
  • PFSense
  • PHP
  • Powershell
  • Python
  • Sanallastirma
  • SAP-ABAP
  • SCOM 2012
  • SEO
  • Sharepoint 2010
  • Sharepoint 2013
  • Silverlight
  • Sistem Analiz ve Tasarımı
  • SQL Server
  • Symantec
  • TFS
  • T-SQL
  • Ubuntu
  • VB.NET
  • Veritabanı Yönetim Sistemleri
  • Visual Studio
  • VMware
  • WCF
  • Web Hosting
  • Windows 8
  • Windows Azure
  • Windows Phone 7.1
  • Windows Phone 8
  • Windows Server
  • Wordpress
  • WPF
  • Xamarin
  • XNA
  • Yazılım Mühendisliği
  • Yöneylem Araştırması
  • ASP.NET MVC
  • Entity Framework
  • Javascript / JQuery
  • LINQ
  • PHP

Son Duyurular

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

IPhone 6 ve IPhone 6 Plus Teknik Özellikleri ve Fiyatı

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

DELL'in Yeni Projesi: USB Bilgisayar (Project Ophelia)

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Windows Phone Youtube Uygulaması Google ve Microsoft ile Yeniden Yapılıyor

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Android ve Apple IOS Telefonlar için Blackberry Messenger (BBM)

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

Nokia Lumia 925 Teknik Özellikleri, Lumia 928 ve 920 ile Karşılaştırması

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

LG Optimus G Pro Özellikleri ve Gözle Video Oynatma Teknolojisi

Custom Activity Designer Geliştirmek

Workflow Foundation Custom Activity Designer Geliştirmek

28.08.2012

Yazar: Burak Selim Şenyurt (Google+)

Kategori: C#.Net

2090

 Merhaba Arkadaşlar,

İnsanın kendisini en çok geliştireceği yer gerçek çalışma sahaları/ortamlarıdır. Ortaya konan ihtiyaçlar ne zaman ki sizin kullanmakta olduğunuz araçların(Tools) sınırlarını zorlamaya başlar, bu noktadan itibaren içerisine gireceğiniz her çeşit mücadele size inanılmaz derece tecrübe ve bilgi katacaktır. Tabi bu know-how bilgisini saklayabilir, kendiniz için dökümante edebilir veya kuralları çerçevesinde paylaşabilirsiniz Wink Geçtiğimiz günlerdeWorkflow Foundation tarafında bir Component Set' in geliştirilmesi üzerine açılan POC(Proof of Concept) projesinde görev aldım. Bu anlamda yoğun bir şekilde Custom Activity Designerkonusu ile yakın ilişki içerisinde yer almam gerekti. Workflow Foundation' ın bileşen seti her ne kadar geniş bir yelpazeye sahip olsa da, özellikle uygulama geliştiricilerin hızlı bir şekilde Workflow(Flow Chart, Sequential vb) tasarlaması gerektiği durumlarda, işleri kolaylaştıracakComponent setlerinin üretilmesi son derece önemlidir. Ne varki XAML tabanlı çalışanActivity Designer örnekleri, Visual Studio IDE' si ile pek kardeşçe yaşamamaktadır(Bu durumun Visual Studio 2012' de devam etmediğini umuyorum). Dikkat edilmesi gereken pek çok nokta ve ip ucu bulunmakta. Dilerseniz ne demek istediğimi örnek bir senaryo üzerinden görmeye çalışalım. 

Senaryomuzda metod adlarını ve bu fonksiyonlara bağlı parametre listelerini gösteren basit birWorkflow Activity bileşenini tasarlamaya çalışıyor olacağız. Bileşenimiz standart bir Code/Native Activity’ den farklı olarak görsel arayüze sahip olacak ve Visual Studio IDE’ si içerisinden de kullanılabilecek. Bir başka deyişle ToolBox sekmesinden designer ortamına sürükleyip bıraktığımızda, IDE kullanıcısı ile etkileşim içerisinde olacak. Dolayısıyla Activity Designer tipini ele alacağımız bir örnek üzerinde çalışıyor olacağız. İlk olarak projelerimizi oluşturarak işe başlayalım. Bu anlamda Solution içeriğini aşağıdaki şekilde görüldüğü gibi tasarlayabiliriz.

Solution yapısı oldukça önemlidir. Activity projesi NativeActivity türevli tipleri barındırıyor iken,Design kütüphanesinde sadece görsel tasarımlar yer alacaktır. Azon.Workflow.Activity projesiActivity Library tipinden iken Azon.Workflow.Activity.Design, Activity Designer Librarytipindendir. Burada Visual Studio 2010 IDE’ sinin beklediği bir isimlendirme standartı bulunmaktadır. Buna göre, Component’ in görsel arayüzünün tasarlanacağı kütüphane adının mutlaka Design kelimesi ile bitmesi gerekmektedir(Bu bilgiyi bulmak oldukça fazla vakit kaybına neden oldu. Ben en başından söylemek istiyorum Wink )

Yolumuza Native Activity bileşenimizi geliştirerek devam edelim. Azon.Workflow.Activitykütüphanesi içerisinde aşağıdaki sınıf diagramında görülen tipleri üretiyor olacağız. Senaryomuza göre bileşenimiz, kaynak bir listede yer alan metod adlarını ve bunlara ait parametreleri gösteriyor olacak. İlk hedefimiz bu.

Şimdi tiplerimiz içeriklerini biraz değerlendirelim.

InstanceMethodActivity.cs

using System.Activities;

namespace Azon.Workflow.Activity
{
    public sealed class InstanceMethodActivity
        :NativeActivity<object>
    {
        public InArgument<string> Description { get; set; }
        public string MethodName { get; set; }

        protected override void Execute(NativeActivityContext context)
        {
            //TODO@Burak burada bir takım kodlar işletilir
        }
    }
}

InstanceMethodActivity, türetilemeyen(Sealed) ve NativeActivity<object> türevli bir tiptir.CodeActivity türevli tiplere benzer olarak, çalışma zamanındaki işlerini Execute metodu içerisinde icra etmektedir. Örneğimizde söz konusu Activity bileşeni için herhangibir Runtime işlemi uygulatmıyor olacağız. Asıl hedefimiz Visual Studio 2010 IDE' sinde Design Time Support' unu sağlayabilmektir. Tipimizin içerisinde InArgument<string> tipinden Description ve stringtüründen MethodName isimli iki özellik(Property) yer almaktadır. Designer tarafında işimize yarayacak olan sınıflar ise InstanceMethod, InstanceMethodParameter, ParameterType(Enum sabiti) ve InstanceMethodList' tir.

namespace Azon.Workflow.Activity
{
    using System.Collections.Generic;

    public class InstanceMethod
    {
        public string Name { get; set; }
        public List<InstanceMethodParameter> Parameters{ get; set; }
    }
}

InstanceMethod, aslında bir metodun adını ve parametrik yapısını taşımak üzere tasarlanmış birPOCO(Plain Old Clr Object) tipidir. Parameters özelliği InstanceMethodParameter tipindengeneric bir List koleksiyonudur ve ilgili sınıfın içeriği de aşağıdaki gibidir.

namespace Azon.Workflow.Activity
{
    public class InstanceMethodParameter
    {
        public string Name { get; set; }
        public string DotNetType { get; set; }
        public ParameterType ParameterType{ get; set; }
    }
}

Bu tip içerisinde ise sembolik olarak metod parametrelerine ait çeşitli bilgiler yer almaktadır. Örneğin parametrenin adı, .Net Framework Common Type System deki karşılığı gibi. ParameterTypeenum sabiti ile de ilgili parametrenin ne çeşitte olduğu belirtilmektedir.

namespace Azon.Workflow.Activity
{
    public enum ParameterType
    {
        Ref,
        Out,
        Standart,
        Return,
        Params
    }
}

Bu kütüphane içerisindeki en önemli tip ise ObservableCollection<InstanceMethod> türevli olan InstanceMethodList' dir.

namespace Azon.Workflow.Activity
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    public class InstanceMethodList
        :ObservableCollection<InstanceMethod>
    {
        public InstanceMethodList()
        {
            Add(new InstanceMethod
            {
                Name = "Sum",
                Parameters = new List<InstanceMethodParameter>{
                    new InstanceMethodParameter{ Name="X", DotNetType="System.Int32", ParameterType= ParameterType.Standart},
                    new InstanceMethodParameter{ Name="Y", DotNetType="System.Int32", ParameterType= ParameterType.Standart},
                    new InstanceMethodParameter{ Name="Result", DotNetType="System.Int32", ParameterType= ParameterType.Return}
                }
            });
            Add(new InstanceMethod
            {
                Name = "TotalSum",
                Parameters = new List<InstanceMethodParameter>{
                    new InstanceMethodParameter{ Name="Values", DotNetType="System.Int32[]", ParameterType= ParameterType.Params},
                    new InstanceMethodParameter{ Name="Result", DotNetType="System.Int32", ParameterType= ParameterType.Return}
                }
            });
            Add(new InstanceMethod
            {
                Name = "CallSp",
                Parameters = new List<InstanceMethodParameter>{
                    new InstanceMethodParameter{ Name="SpName", DotNetType="System.String", ParameterType= ParameterType.Standart},
                    new InstanceMethodParameter{ Name="ResultSet", DotNetType="System.Data.DataTable", ParameterType= ParameterType.Ref}
                }
            });
        }
    }
}

Bu tip aslında Activity Designer' ın XAML tabanlı içeriğinde ele alacağımız Data Binding işlemleri için kullanılmaktadır. ObservableCollection türevli olmasının sebebi de budur. Amacımız tipin kendisini ComboBox ve DataGrid kontrollerine bağlamaktır. Yapıcı(Constructor) metod içerisinde, örnek metod bilgilerinin eklendiği görülmektedir. Elbetteki bir gerçek hayat senaryosunda ilgili içeriklerin farklı veri ortamlarından tedarik edilmesi de düşünülebilir. Örneğin bu bilgileri bir servis üzerinden veya doğrudan erişilebilen ve InProc modda kullanabildiğimiz bir Assemblyiçerisinden de getirtebiliriz.

Gelelim bileşenimizin arayüzünü tasarlayacağımız Activity Designer öğesine.Azon.Workflow.Activity.Design kütüphanesinde oluşturacağımızInstanceMethodActivityDesigner.xaml tipinin içeriğini aşağıdaki gibi tasarlayabiliriz.

<sap:ActivityDesigner x:Class="Azon.Workflow.Activity.Design.InstanceMethodActivityDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" 
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
    xmlns:Model="clr-namespace:System.Activities.Presentation.Model;assembly=System.Activities.Presentation"
    xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
    xmlns:activity="clr-namespace:Azon.Workflow.Activity;assembly=Azon.Workflow.Activity"
    mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <sap:ActivityDesigner.Resources>
        <ResourceDictionary x:Uid="ResourceDictionary_0">
            <sapc:ModelToObjectValueConverter x:Key="ModelToObjectValueConverter" />
            <ObjectDataProvider x:Key="dsInstanceMethods" ObjectType="{x:Type activity:InstanceMethodList}">
            </ObjectDataProvider>

            <DataTemplate x:Key="Collapsed">
                <StackPanel Orientation="Horizontal">
                    <TextBlock VerticalAlignment="Center" Margin="5" Text="Method Caller" />
                </StackPanel>
            </DataTemplate>

            <DataTemplate x:Key="Expanded">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Metodlar" Grid.Row="0"/>
                    <ComboBox x:Name="cmbInstanceMethods" Grid.Row="1" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" />
                    <TextBlock Text="Metod Parametreleri" Grid.Row="2"/>
                    <DataGrid x:Name="grdMethodParameters" Grid.Row="3" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}, Path=Parameters}"/>
                </Grid>
            </DataTemplate>
            <Style x:Key="ExpandOrCollapsedStyle" TargetType="{x:Type ContentPresenter}">
                <Setter Property="ContentTemplate" Value="{DynamicResource Expanded}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=ShowExpanded}" Value="true">
                        <Setter Property="ContentTemplate" Value="{DynamicResource Collapsed}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>

        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <Grid>
        <ContentPresenter Style="{DynamicResource ExpandOrCollapsedStyle}" Content="{Binding}" />
    </Grid>
</sap:ActivityDesigner>

Vuuuuu!!! Sealed Biraz korkutucu bir içerik gibi görünebilir. Ama korkmayın. Tek tek açıklamaya çalışalım.

Herşeyden önce bileşenimiz içerisinde bazı Static Resource' lar tanımlandığı görülmektedir.dsInstanceMethods isimli ObjectDataProvider, InstanceMethodList isimli sınıfa bağlanmaktadır. Dolayısıyla XAML içerisinde yer alan bileşenler bu veri kaynağına bağlanıpInstanceMethod nesne örnekleri ile etkileşimde bulunabilirler. Örneğin cmbInstanceMethodsisimli ComboBox kontrolü, ItemsSource özelliğine static bir veri kaynağı olarak buObjectDataProvider örneğini bağlamıştır. DisplayMemberPath özelliğine atanan Name değeri ise, InstanceMethod  örnekleri içerisindeki Name özelliğini işaret etmekte olup ComboBox' un üzerinde nelerin gösterileceğini belirtmektedir. ComboBox üzerinde hareket edildikçe alt tarafta yer alan grdMethodParameters isimli DataGrid içeriğininde, ilgili metoda ait parametre listesi ile doldurulması beklenmektedir. Bu nedenle her iki bileşenin IsSychnronizedWithCurrentItemözelliği true değerine sahiptir. DataGrid bileşeninin ItemsSource özelliği de static veri kaynağı olan dsInstanceMethods' a bağlanmıştır. Ama!

Path özelliğinin değerine dikkat edelim. Parameters değeri aslında InstanceMethodListsınıfındaki özelliğin adıdır. Dolayısıyla ComboBox kontrolünde bir öğe seçildiğinde, buna bağlıParameters özelliğinin karşılığı olan liste, DataGrid içerisine basılıyor olacaktır. Görüldüğü üzere tipik olarak bir WPF Data Binding işlevselliği söz konusudur. Bunun dışında kalan kısımlarda bileşenin Collapse veya Expand edilmesi hallerinde nasıl görüneceği ifade edilmiştir. Dikkat edilecek olursa iki adet DataTemplate elementi vardır. Bunlardan birisi Collapsed diğer iseExpanded olarak isimlendirilmiştir. Son satırlarda yer alan Grid elementi içerisindekiContentPresenter' da buna uygun olacak şekilde bileşenin Collapsed veya Expanded olarakdesigner üzerinde gösterilebilmesini sağlamaktadır(Ne varki ben Collapsed hale bir türlü getirmeyi başaramadım. Yani örneğimizde şimdiden bir Bug' ımız olduğunu ifade etmek isterim Undecided )

Bileşenimizin XAML içeriğini bu şekilde oluşturmak yeterli değildir. Ayrıca Visual Studio Designer' ına söz konusu bileşeni bildirmemiz gerekmektedir. Bunun için ilk olarak Activity Designer sınıfının koda tarafını aşağıdaki hale getirmeliyiz.

using System.Activities.Presentation.Metadata;
using System.ComponentModel;

namespace Azon.Workflow.Activity.Design
{
    public partial class InstanceMethodActivityDesigner
    {
        #region Constructors and Destructors

        public InstanceMethodActivityDesigner()
        {
            this.InitializeComponent();
        }

        #endregion

        #region Public Methods

        public static void RegisterMetadata(AttributeTableBuilder builder)
        {
            builder.AddCustomAttributes(
                typeof(InstanceMethodActivity),
                new DesignerAttribute(typeof(InstanceMethodActivityDesigner)),
                new DescriptionAttribute("Instance Method Activity"));
        }

        #endregion
    }
}

Sınıf içerisindeki en önemli metod RegisterMetadata isimli static fonksiyondur. Bu metod içerisinde parametre olarak gelen Attribute tablosuna bazı bildirimlerde bulunularak yeniniteliklerin(Attribute) ilave edilmesi sağlanmaktadır. Hatta dilerseniz burada Component için birIcon(16X16 boyutlarında bir PNG olabilir) dahi belirtebilirsiniz. Biz şimdilik bu detayı atlıyor olacağız.

Peki söz konusu static metod nerede çağırılacaktır? Undecided Bunun içinAzon.Workflow.Activity.Design kütüphanesine IRegisterMetadata arayüzünü implemente eden bir sınıfın eklenmesi gerekmektedir. IRegisterMetadata arayüzünden gelen Register metodu içerisinde ise, InstanceMethodActivityDesigner sınıfına dahil edilmiş olan RegisterMetadataisimli static metod çağrısı gerçekleştirilmektedir.

using System.Activities.Presentation.Metadata;
namespace Azon.Workflow.Activity.Design
{
    public sealed class ActivityLibraryMetadata
        : IRegisterMetadata
    {
        public void Register()
        {
            RegisterAll();
        }

        public static void RegisterAll()
        {
            var builder = new AttributeTableBuilder();
            InstanceMethodActivityDesigner.RegisterMetadata(builder);
            MetadataStore.AddAttributeTable(builder.CreateTable());
        }
    }
}

Burada kullanılan sınıfın adının çok önemi yoktur. Nitekim Visual Studio IDE' si, kendi çalışma zamanı ortamında, ilgili Activity Designer kütüphanesinde IRegisterMetadata arayüzünü uygulamış olan bir tipe bakmaktadır. Tipik bir Plug-In tasarım mantığı olduğunu rahatlıkla ifade edebiliriz.

Artık bileşenimizi deneyebiliriz demek isterdim ama son olarak yapmamız gereken ufak bir işlem daha var. Adı Design kelimesi ile biten kütüphanenin dll çıktısının, NativeActivity bileşenlerini içeren kütüphanenin olduğu yere doğru yapılması gerekmektedir. Aşağıdaki şekilde görüldüğü gibi.

Artık basit bir Workflow üzerinden bileşenimizi deneyebiliriz. Bileşenimiz otomatik olarak Toolboxsekmesinde görünecektir. İşte Visual Studio 2010 çalışma ortamına ait bir kaç örnek görüntü.

Sum metodu seçildiğinde

CallSp metodu seçildiğinde

Görüldüğü üzere bileşenimiz içerisinde Data Binding tekniklerini de kullanarak bir etkileşim gerçekleştirmeyi başardık. Şimdi bileşenimizi biraz daha geliştirmeyi deniyor olacağız. Buna göreComboBox kontrolünde bir öğe seçildiğinde, Name alanının değerinin, o ankiInstanceMethodActivity' ye ait Property' lerden MethodName alanında gösterilmesini sağlamaya çalışacağız. Bu bonus senaryoda işi zorlaştıran kısım şu;

ComboBox bileşeni içerisinde Binding sebebi ile InstanceMethodList sınıfına ait değerler taşınmaktadır. Bu değerler InstanceMethod türünden nesne örnekleridir aslında.InstanceMethodActivity bileşeninin, MethodName özelliği ise string tipindendir. DolayısıylaComboBox kontrolünün SelectedValue özelliği içerisinde XAML tarafında bildirilecek şekilde özel bir Convert işleminin uygulanması gerekmektedir. Bu amaçla öncelikli olarak bir Converter tipiniAzon.Workflow.Activity kütüphanesine aşağıdaki gibi ilave edelim.

namespace Azon.Workflow.Activity
{
    using System;
    using System.Globalization;
    using System.Windows.Data;


    public class InstanceMethodToMethodNameConverter
        :IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null; //BURASI SİZE ÖDEV OLSUN
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            InstanceMethod instanceMethod = (InstanceMethod)value;
            return instanceMethod.Name;
        }
    }
}

InstanceMethodToMethodNameConverter tipi, System.Windows.Data isim alanında(ki PresentationFramework.dll assembly' ının projede referans edilmesi gerekmektedir) yer alanIValueConverter arayüzünü(Inteface) uygulamaktadır. Buna göre TwoWay Binding' i destekleyecek şekilde Convert ve ConvertBack metodlarının implemantasyonunu istemektedir.Convert metodu, Properties penceresinden girilen değere göre ComboBox içerisinde ilgili öğeye gidilmesini sağlamaktadır. ConvertBack metodu ise tam tersi işlevi üstlenmekte olup, ComboBox'ta seçilen InstanceMethod nesne örneğinin Name özelliğinin değerini Properties penceresindekiMethodName alanına basmaktadır. Tabi söz konusu tipin yazılması yeterli değildir. Bu Convertertipinin XAML tarafında da dekleratif olarak bildirilmesi ve ComboBox bileşeni ile ilişkilendirilmesi gerekmektedir. Bunun için InstanceMethodActivityDesigner.xaml içeriğini aşağıdaki gibi güncellememiz yeterli olacaktır.

<sap:ActivityDesigner x:Class="Azon.Workflow.Activity.Design.InstanceMethodActivityDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" 
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
    xmlns:Model="clr-namespace:System.Activities.Presentation.Model;assembly=System.Activities.Presentation"
    xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
    xmlns:activity="clr-namespace:Azon.Workflow.Activity;assembly=Azon.Workflow.Activity"
    mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
    <sap:ActivityDesigner.Resources>
        <ResourceDictionary x:Uid="ResourceDictionary_0">
            <sapc:ModelToObjectValueConverter x:Key="ModelToObjectValueConverter" />
            <activity:InstanceMethodToMethodNameConverter x:Key="MethodToMethodNameConverter"/>
            <ObjectDataProvider x:Key="dsInstanceMethods" ObjectType="{x:Type activity:InstanceMethodList}">
            </ObjectDataProvider>

            <DataTemplate x:Key="Collapsed">
                <StackPanel Orientation="Horizontal">
                    <TextBlock VerticalAlignment="Center" Margin="5" Text="Method Caller" />
                </StackPanel>
            </DataTemplate>

            <DataTemplate x:Key="Expanded">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Metodlar" Grid.Row="0"/>
                    <ComboBox x:Name="cmbInstanceMethods" Grid.Row="1" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" SelectedValue="{Binding Path=ModelItem.MethodName, Mode=TwoWay, Converter={StaticResource MethodToMethodNameConverter}}" />
                    <TextBlock Text="Metod Parametreleri" Grid.Row="2"/>
                    <DataGrid x:Name="grdMethodParameters" Grid.Row="3" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}, Path=Parameters}"/>
                </Grid>
            </DataTemplate>
            <Style x:Key="ExpandOrCollapsedStyle" TargetType="{x:Type ContentPresenter}">
                <Setter Property="ContentTemplate" Value="{DynamicResource Expanded}" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=ShowExpanded}" Value="true">
                        <Setter Property="ContentTemplate" Value="{DynamicResource Collapsed}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>

        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    <Grid>
        <ContentPresenter Style="{DynamicResource ExpandOrCollapsedStyle}" Content="{Binding}" />
    </Grid>
</sap:ActivityDesigner>

Buna göre ComboBox kontrolünde bir Metod adı seçilirse bu Properties penceresine de bu isim yansıyacaktır. Böylece developer' ın işi biraz daha kolaylaştırılmış olmaktadır.

Şimdi olayı biraz daha renklendireceğiz. Örneğin Visual Studio Designer' ı üzerinde çalışırken,Activity bileşenlerine ait event methodları kullanmak istediğinizi ve hatta bu event metodlar içerisinde, diğer kontrollerin içeriklerine ulaşmak istediğimizi düşünelim. Bu senaryoyu irdelemek için InstanceMethodActivityDesigner.xaml içeriğine bir Button kontrolü ekleyerek ilerleyebiliriz.

<DataTemplate x:Key="Expanded">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="Metodlar" Grid.Row="0"/>
                    <ComboBox x:Name="cmbInstanceMethods" Grid.Row="1" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True" SelectedValue="{Binding Path=ModelItem.MethodName, Mode=TwoWay, Converter={StaticResource MethodToMethodNameConverter}}" />
                    <TextBlock Text="Metod Parametreleri" Grid.Row="2"/>
                    <DataGrid x:Name="grdMethodParameters" Grid.Row="3" IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Source={StaticResource dsInstanceMethods}, Path=Parameters}"/>
                    <Button x:Name="btnCatchParameters" Click="btnCatchParameters_Click" Content="Parametreleri Çek" Grid.Row="4">
                    </Button>
                </Grid>
            </DataTemplate>

btnCatchParameters isimli Button kontrolünün Click olay metodunun yüklendiği görülmektedir. Bu olay metodu çok doğal olarak InstanceMethodActivityDesigner.cs içerisine açılıyor olacaktır. Olay metodu içeriğini aşağıdaki kod parçasında görüldüğü gibi geliştirebiliriz.

private void btnCatchParameters_Click(object sender, System.Windows.RoutedEventArgs e)
{
    Grid parent=((Grid)((Button)e.Source).Parent);
    foreach (UIElement control in parent.Children)
    {
        DataGrid grid=control as DataGrid;
        if(grid!=null)
        {
            StringBuilder builder = new StringBuilder();
            foreach (var item in grid.ItemsSource)
            {
                builder.AppendLine(item.ToString());
            }
            MessageBox.Show(builder.ToString(),"Parametreler");
        }
    }                          
}

Olay metodu içerisindeki felsefe oldukça basittir. Button kontrolü aslında bir Grid içerisinde yer almaktadır ve DataGrid bileşeni de aynı seviyede(Level) durmakta olan bir elementtir. DolayısıylaButton bileşeninin Parent elementine(Container da diyebiliriz) çıkıp, tüm alt kontrolleri dolaşabilir ve Grid tipinde olana vardığımızda da ItemsSource özelliğine ait koleksiyon içeriğini ele alabiliriz. Kulağımızı farklı bir şekilde tuttuğumuzu ifade edebiliriz aslında ama şu anda elimizden en iyi çözüm bu. Böylece Visual Studio Designer' ı içerisindeyken, DataGrid elementlerine ve seçili olan metodun parametre listesine ulaşmamız mümkün olacaktır. Aynen aşağıdaki şekilde görüldüğü gibi.

Görüldüğü üzere Custom Activity geliştirmek kolay olsa da, bu bileşeni Designer desteğine sahip olacak şekilde genişletmek bir kaç ipucu içeren ve dikkat edilmesi gereken bir süreci gerektirmektedir. Geliştirmiş olduğumuz örnekte bazı eksik kısımlar da bulunmaktadır. ÖrneğinXAML tarafında dekleratif olarak Event bazlı etkileşimler çok fazla ele alınmamıştır.(Bir veritabanı bağlantısını seçtiren ve hatta design tarafında bir SQL sorgusunu çalıştırtıp sonuçları bir DataGridkontrolüne basan bir Activity Designer yazmaya çalıştığınızı hayal edin. Üstelik Connection' ı tanımladığınızda Test' de edebilmelisiniz vs Wink ) Bu konuda detaylı ve derinlemesine araştırmalarıma devam ediyorum. Yeni bilgiler edindikçe sizinle paylaşmaya gayret ediyor olacağım. Böylece geldik bir yazımızın daha sonuna. Tekrardan görüşünceye dek hepinize mutlu günler dilerim.

WritingDesignerActivityV2.zip (155,91 kb)

Yazar Hakkında

Burak Selim Şenyurt

Burak Selim Şenyurt

buraksenyurt.com

Yıldız Teknik Üniversitesi Matematik Mühendisliği mezunu olan Şenyurt, 1999 yılında profesyonel olarak adım attığı yazılım dünyasında, 2003 yılından beri Microsoft .Net teknolojileri ile ilgilenmektedir. Yazılım hayatına Assist Line isimli Call Center firmasında Delphi programcısı olarak başlayan Şenyurt sonrasında, sırasıyla Bizitek(Junior Developer), Netron(Master Trainer), Citibank(Outsource Senior Software Developer), Innova(Application Development Consultant), ve TCM(Software Architect) firmalarında görev almıştır. Su anda ING Bank bünyesinde Kıdemli Yazılım Danışmanı olarak görev yapmaktadir. 2006, 2007 yıllarında C#, 2008,2009,2010 yıllarında ise Connected System Developer kategorisinde Microsoft MVP seçilen Şenyurt, evli ve 1 çocuk babasıdır. C# diline olan düşkünlüğü, oğluna S(h)arp adının verilmesinde önemli bir etken olmustur.

Sosyal Medya

ORANLAR

  • 2090izleme

Arkadaşlarınla Paylaş

  • Tweet

0 Yorum

Yorum Yaz / Soru Sor

Lütfen yorum yazmak veya soru sormak için üye girişi yapınız.

Son Yorumlar

  • Hocam Link başka sayfaya yönlendiriyor.
  • merhaba benim merak ettiğim bir konu var y...
  • Merhaba download linki çalışmıyor. Rica et...
  • Nevzat Bey selamlar, Açıkçası bizler a...
  • Parametreleri Cache İşleminden Yalıtma kon...

En Güncel Sorular

  • Bilgilendirme maili (C#.Net)
  • Power Pivot (Sharepoint 2010)
  • BigInteger, BigDecimal (Asp.Net ve Asp.Net MVC)
  • visual C# ile asp nette veritabanı islemleri (Asp.Net ve Asp.Net MVC)
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ? (Sharepoint 2010)

En Son Cevap Verilen Sorular

  • Bilgilendirme maili
  • BigInteger, BigDecimal
  • visual C# ile asp nette veritabanı islemleri
  • Share Point ile Dosya Arşiv Yönetim Sistemi yapılabilir mi ?
  • txt dosyasına veri yazma

Twitter

Takip et: @yazilim_dilleri

En Çok Okunanlar

Elif BAYRAKDAR

C# ile SQL Server Bağlantısı, Insert, Update ve Delete Sorguları

23.05.2013

  • 120172
  • 0
Hakan Keskin

C# ile Windows Service Projesi Oluşturma, Debug Etme ve Setup Hazırlama

17.12.2013

  • 65293
  • 0
batuhan avlayan

Php - Mail Gönderme (İletişim Formu)

02.09.2013

  • 48406
  • 0

Sponsorlar

KODLAB
Pluralsight
Exchange server is
Office 365
YAZILIM DİLLERİ
Yukarı Çık
  • Hakkımızda
  • Facebook
  • Twitter
  • RSS

© Yazılım Dillerinin Buluşma Noktası | Kaynak belirtildiği sürece makaleler kopyalanabilir.
YazilimDilleri.Net sitesinde yer alan kullanıcıların oluşturduğu tüm içeriklerin yayınlanması ile ilgili yasal yükümlülükler içeriği oluşturan kullanıcıya aittir, YazilimDilleri.Net hiçbir şekilde sorumlu değildir.

Kapat

Giriş Yap

Kullanıcı Adı

Şifre

Şifremi Unuttum

KULLANICI GİRİŞİ