SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Workflow Foundation 4が導く新しい開発スタイル

「Workflow Foundation 4」の中心~アクティビティの作成

Workflow Foundation 4が導く新しい開発スタイル(2)

GUIを提供するアクティビティデザイナー

 WF 4ではコードのみではなくワークフローデザイナー上でワークフローの実装を行うことができます。その際に、プロパティダイアログなどに設定するのではなく、デザイナー上に直接入力を行えるようにするための機能としてアクティビティデザイナーが用意されています。アクティビティデザイナーはWPFにて実装を行い、WF 4のアクティビティに対してバインディングを行う形で利用します。簡単な例を次に示します。

サンプルコード(XAML)
<sap:ActivityDesigner x:Class="SampleActivityDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
    xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation" 
    mc:Ignorable="d" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    d:DesignHeight="74" d:DesignWidth="202">
        
    <sap:ActivityDesigner.Resources>
        <ResourceDictionary>
            <sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70" />
            <ColumnDefinition Width="130*" />
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="値を!" 
                    HorizontalAlignment="Center" VerticalAlignment="Center" />
        <sapv:ExpressionTextBox Grid.Column="1"
              Expression="{Binding Path=ModelItem.RecvValue, Mode=TwoWay,
                Converter={StaticResource ArgumentToExpressionConverter},
                ConverterParameter=In}"
              OwnerActivity="{Binding Path=ModelItem}"
              MinLines="1" MaxLines="1" />
    </Grid>
</sap:ActivityDesigner>

 基本クラスActivityDesignerを継承した形で実装を行います。Express Editionを利用している場合はWPFユーザーコントロールを新規で追加することでコーディングを行うことが可能です。上記XAMLをデザイン画面で見ると次のように表示されます。

アクティビティデザイナー
アクティビティデザイナー

 アクティビティデザイナーと言っても、その実装方法はWPFのそれと何ら変わりがないことが理解いただけたと思います。WF 4固有の実装は、XAMLの中で行われているプロパティとのバインディング、そして利用しているExpressionTextBoxコントロールです。バインディングはModelItem編集コンテキストを通して行い、アクティビティとして実装しているプロパティとアクティビティデザイナー上の項目とを結びつけます。

 ExpressionTextBoxコントロールはWF 4独自に用意された、値や式を入力させるための特殊なテキストボックスです。Visual Studio自身もアクティビティの編集にてこのコントロールを利用しています。ここで入力できるのはVB式と呼ばれるVBのコードのみですが、WF 4.5からはC#式も利用することが出来るようになります。通常のTextBoxを利用することも可能ですが、WF 4ではhogeValue.ToStringといった式そのものを設定したりするケースが多々発生します。このようなケースではExpressionTextBoxを通して入力された式を適切なクラスに変換し、ワークフローに設定することが可能になります。

 そしてもう1つの特徴として、機能拡張用インターフェースが公開されており、独自の実装を行うことで式や値を入力する際の入力支援を作り込むこともできるようになっています。例えばVisual Studioでは必須の機能であるインテリセンスを提供させることも可能です。アクティビティデザイナーを利用するアクティビティの実装は次のようになります。

サンプルコード(Visual Basic)
mports System.Activities
Imports System.ComponentModel

<Designer(GetType(SampleActivityDesigner))>
Public Class SampleActivity
    Inherits CodeActivity

    Public Property RecvValue As InArgument(Of String)

    Protected Overrides Sub Execute(context As System.Activities.CodeActivityContext)
        Console.WriteLine(context.GetValue(Me.RecvValue) + " が設定されています")
    End Sub
End Class
サンプルコード(C#)
using System;
using System.Activities;
using System.ComponentModel;
namespace SampleDesigner
{
    [Designer(typeof(SampleActivityDesigner))]
    public class SampleActivity: CodeActivity
    {
        public InArgument RecvValue { get; set; }
        
        protected override void Execute(CodeActivityContext context)
        {
            Console.WriteLine(context.GetValue(this.RecvValue) + " が設定されています");
        }
    }
}

 Designer属性を用いて、アクティビティで利用するアクティビティデザイナーを指定しています。設定後、作成したアクティビティをワークフローデザイナー上にドロップすると、アクティビティデザイナーが利用できます。

 Express EditionではワークフローデザイナーがVisual Studioに組み込まれていないため、直接ワークフローのXAMLを記載する必要があります(ワークフローデザイナーを自作アプリケーションで利用する方法については次回解説予定です)。サンプルとして次のようなワークフローを作ってみます。

プロジェクトの参照設定
プロジェクトの参照設定

 実装しているアクティビティはVisual Studioで自動に認識し、ワークフローの編集時にはツールボックスにそのアクティビティが表示されます。もし表示されていない場合はビルドを行ってください。

 ワークフローとしては、今作成したアクティビティに対してデザイナー上から”サンプルデザイナー”という文字列を設定しただけの簡単なものです。先ほどのExpressionTextBoxの説明の際で「式自身を設定する」と書きましたが、上記画面では文字列を設定するのにダブルクォーテーションで囲っている点に注意してください。ここで設定するものはVB式である必要があります。

 このワークフローをXAMLで出力すると以下のようになります。

サンプルコード(XAML)
<Activity 
    mc:Ignorable="sap" x:Class="Workflow1" 
    mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" 
    xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" 
    xmlns:local="clr-namespace:SampleDesigner" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" 
    xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" 
    xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <local:SampleActivity RecvValue="["サンプルデザイナー"]" />
</Activity>

 このXAMLをWorkflow1.xamlとしてプロジェクトに組み込みます。後はワークフローをホストするロジックを用意します。

サンプルコード(Visual Basic)
Imports System.Activities
Module Module1

    Sub Main()
        WorkflowInvoker.Invoke(New Workflow1())
        Console.ReadLine()
    End Sub

End Module
サンプルコード(C#)
using System;
using System.Activities;
namespace SampleDesigner
{

    class Program
    {
        static void Main(string[] args)
        {
            WorkflowInvoker.Invoke(new Workflow1());
            Console.ReadLine();
        }
    }
}

 実行すると、以下の表示が確認できます。

サンプルワークフローの実行結果
サンプルワークフローの実行結果

次のページ
まとめ

修正履歴

この記事は参考になりましたか?

Workflow Foundation 4が導く新しい開発スタイル連載記事一覧

もっと読む

この記事の著者

小尾 智之(オビ トモユキ)

地方企業に勤めるインディープロレス好きなエンジニア。VB + SQL Server のシステム構築を主な業務としていましたが、元々の性格もあり色々な物に目移り中。Ahf というハンドルネームで所属する北海道の技術コミュニティ CLR/H(http://clr-h.jp) での活動など行っていましたが、最近か...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/6652 2012/07/13 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー