2011年4月4日月曜日

UI と Activity の連携(1)

Workflow と Activity、そしてフォームやコンソールなどの UI との連携は何通りも方法があります。最初は最も手っ取り早い方法、Activity 内部で画面を生成してやりとりするやり方を。

Protected Overrides Sub Execute(ByVal context As CodeActivityContext)

    Dim inputText As String = ""
    Using dlg As New Form1
        dlg.ShowDialog()
        inputText = dlg.result
    End Using

    context.SetValue(Me.Result, inputText)
End Sub

例えば適当な Form を用意してそれを Activity 実行時に表示、入力された値を Form のプロパティとして戻してもらうような Activity にします。この際、Activity のプロパティは InArgument や OutArgument を利用するのがベターですが、呼び出される Form 側ではなんでも構いません。実際に利用する場合は、何らかの構造体や DataSet ライクなクラスを用意するのがやりやすいのではないか、と思います。

そしてこのような感じで Workflow を定義。

WF4_1

InputDialog と書かれている Activity が上記サンプルコードの Activity、Display と表示されているのが、前回のサンプルでも利用した渡されたプロパティを表示するだけの Activity です。

Activity を Workflow に設定後、変数を定義し UI と Activity の間で利用するようにします。作成した変数名を InputDialog・DIsplay それぞれの Activity にて受け渡し用に定義したプロパティに設定します。ここで「変数名」を設定するのが通常のプロパティとちょっと異なるところです。その後実行すると、

WF4_2

本気で適当に用意した Form が表示されます。適当な文章を入力し OK ボタンを押すと、呼び出し元の Activity.Execute メソッド内部で Context を通した形で Workflow 上の変数に値が設定されます。

WF4_3

DIsplayActivity 側では、設定された変数名を Context から取得、そのまま表示されます。

このような形で非常に簡単に Activity 間での情報のやりとりが可能になってます。これを発展させると、UI 部と処理ロジックが「完全」に分離させることができるようになります。そしてそのロジック部分は上記のような Workflow ですので、プログラマでなくとも処理の変更が可能になります。勿論、Activity 等の作り込み次第で更に簡単に、または難しくなることはありますが、非常に保守性の高いアプリケーションをより作成しやすくなるのは間違いないのではないか、と思います。

2011年4月2日土曜日

Assign アクティビティ

ちょっとずつ既存 Activity の説明も混ぜていきます。最初は変数設定のできる非常に重要な Assign アクティビティ。

単純に言えば、変数に対して値を設定する Activity。機能としてはこれだけなんだけど、WF4 ではActivity 同士でのデータやりとりが非常に簡単になったのも、これがあるからだったり。

image

ワークフロー上で上記の様に変数を作成すると、このワークフロー内部(スコープの設定で変更できる)で共用することができるようになります。今回のサンプルでは Assign 以外にもう一つ自前で作成した Display アクティビティなんてものを用意しました。ロジックはこんな感じのデバッグ用みたいなものです。

Public NotInheritable Class DisplayActivity
    Inherits CodeActivity

   '文字列型のアクティビティ入力引数を定義します
    Property Text() As InArgument(Of String)

    ' アクティビティが値を返す場合は、CodeActivity(Of TResult) から派生して、
    ' Execute メソッドから値を返します。
    Protected Overrides Sub Execute(ByVal context As CodeActivityContext)
       'テキスト型の入力引数のランタイム値を取得します
        Dim inpText = context.GetValue(Me.Text)
        MessageBox.Show(inpText)
    End Sub
End Class

InArgument として定義したプロパティは Activity に対して入力用のクチとして利用できるだけでなく、親元のワークフローで定義されている変数の受け渡しも行えます。単純に値をもらうだけであれば、String  なプロパティを定義すれば済むのですが、親元で動的に変化する変数を利用する場合には InArgumet を利用する必要があります。反対にある Activity から値を戻したい場合には OutArgument で定義したプロパティを用意する必要があります。

image

実際に実行するとこのように親元で定義した変数に対して、Assign アクティビティで値を設定、その値を Messagebox で表示することができます。これを応用することで、プログラム間の連携とかも行えるようになります。

既存 Activity のアイコン画像(2)

Activity のアイコン画像は Activity クラス系ではなく AtivityDesigner クラス系で保持している。
これが便利でもあり不便でもあり。Activityをカスタマイズする場合、それをワークフローデザイナー上で色々触る事ができるようにするのは考えておく必要があるんだけど、その場合に重要なのは ActivityDesigner になるんだよね。こいつがワークフローデザイナー上で表示されるものを制御しているので。

そこでいい方法が思いつかなかったのもあり、デザイナー上に表示されたActivityのアイコン画像を抽出し保存、それをリソースとしてしまおうというやり方を今回はとりました。ただ原理はわかったので、そのうち動的にロードするようにするとは思いますです。

ワークフローデザイナー上にドロップした Activity は、デザイナーの Context プロパティを通してアクセスできます。ただしここでアクセスできるのは、WorkflowDesigner.Context.Items に保持されている中で、System.Activities.Presentation.View.Selection というデザイナー上で選択されている Activity、という部分だけです。まぁ実際には選択されている Activity を利用して Root 要素な Activity までアクセスすることもできるので、やればどうにかはなります。

    If designer.Context IsNot Nothing Then
        For Each child In .Context.Items
            If TypeOf child Is System.Activities.Presentation.View.Selection Then
                For Each child2 In DirectCast(child, View.Selection).SelectedObjects
                    ‘ここで Activity (ModelItem) として抽出ができた   
                Next
            End If
        Next
    End If

まずはこのような形でワークフローデザイナー(designer という名前の変数で利用)にて選択されている Activity を取得します。SelectedObjects は IEnumrable(Of ModelItem) という形で取得できるようになっています。そのようにして抽出できた Activity には View プロパティが用意され、そこを通してActivityDesigner にアクセスできるようになっています。試していないのですが単純に Activity のインスタンスを生成した場合、View プロパティに情報が設定されているのであれば動的に抽出もできそうです。

Dim targetDesigner = DirectCast(target.View, ActivityDesigner)
Dim iconBrush = targetDesigner.Icon.Drawing

Dim dv = New DrawingVisual
Using dc = dv.RenderOpen
    dc.DrawDrawing(iconBrush)
End Using

Dim outputBitmap = New RenderTargetBitmap(16, 16, 96, 96, PixelFormats.Pbgra32)
outputBitmap.Render(dv)
Dim enc = New PngBitmapEncoder
enc.Frames.Add(BitmapFrame.Create(outputBitmap))
Using Stm = System.IO.File.Create(targetDesigner.GetType.Name + ".png")
    enc.Save(Stm)
End Using

このような形で ActivityDesigner からアイコン情報を取得し、png フォーマットで保存します。png なのはアイコン情報では透過色が利用されているからで、ここで Bitmap で保存すると後で泣けます。もう一つ注意するのは、ここでは保存する際に ActivityDesigner の Type 名を利用していますが、Activity はすべてにおいて専用の ActivityDesigner を利用している訳ではなく、一部リソースのみ差し替えた状態で利用している物があります。ThrowAtivity とかそういったところでは後でファイル名を手直しする必要があります。まぁここで ActivityDesigner 名ではなく、Activity 名で保存すれば OK なのですがw

このようにして抽出し保存、その後リソースとしておけばExpress Edition であろうとも既存 Activity のアイコン画像には対応できます。

2011年4月1日金曜日

既存 Activity のアイコン画像(1)

色々とやろうとして一番最初に困ったのが「ツールボックス上に追加する Activity のアイコン」。各所で見られるサンプルでは、ToolboxControl に対して ToolboxItemWrapper クラスを利用した形で追加していくんだけど、この場合は「明示的にアイコン画像を指定」しなければ、ツールボックス上に画像が出ない。

で、色々調べていると海外の MSDN Blog でこのような記事が。細かいことは記事を見てもらうとして、ぶっちゃけたところ

Microsoft.VisualStudio.Activities.Dll にリソースあるよ!

ということなんだそうで。ところが、この Dll は Express Edition ではインストールされない類のもので、Standard 以上でなければ入手できないんだよね。まぁ体験版を入れて~、という手段でどうこうできるのでやってみると、こんな感じに。

WF4Design1

見てもらうとわかる通り、大体の Activity はアイコンが表示されるようになったけど、実際にはまだ表示されていない Activity が残っているんだよね。ForEach とか ParallelForEach とか。恐らくは別の Dll にリソースがあるんだろうけど、そこまでは調べてません。

以前の記事ではこのあたりどうしたかというと。

WF4Design2

最初はアイコンなしの状態でツールボックスへ追加、その後その Activity からアイコンイメージを抽出して保存、それをリソースとしておいて利用するという、大元のリソースがバージョンアップして画像変わったら泣くよね!、という方法を利用しています。

その抽出方法については次の記事で。

2011年3月30日水曜日

VS 2010 Express で Workflow 4

以前も WF 3.5 の際に、まずデザイナを用意することろから始めたので今回も同様に始めたんだけど、最初に手を付けた時期は結構昔だったりするので改めて。

VS Express 環境では Workflow のエディタを殆ど利用できない(仮に通常版 VS からテンプレートを移行したとしても、Express の制限上利用できるのは ActivityDesigner くらい)なので、ある程度触ろうとするとどうしてもデザイナーの力が必要になります。

WF4 になってデザイナーのリホスティングとかはすさまじく簡単になったのは、MS 松崎さんのBlog などにもある通り・・・なのですが。ここで提供されているもののうち、ツールボックスは VS で利用しているツールボックスとは別物のため、通常版 VS と同じことをやろうとすると結構壁に阻まれます。

WF4Express

2011/03/30 の時点でここまではできたので、これから少しずつ対応方法などを書いていきます。

2011年3月27日日曜日

第 56 回 CLR/H 勉強会 ~ Rails デイ ~

3/26 に行われた CLR/H 第 56 回勉強会についてのレポートです。
今回は自分がほとんど全く関わり合いのない Rails についての勉強会ということもあり、非常に期待しての参加でした。

CLR/H #56 2011/03/26

セッション 1・2 「たのしい Rails」

CLR/H #56 2011/03/26

CLR/H の運営メンバーでもある @sandinist さんによる Rails についてのセッション。前半はASP.NET MVC との比較や Rails についての基礎知識など、後半はとある教本をもとにしたライブコーディングという流れで行われました。

自分はこれまで全く Rails、Ruby についてふれたことがなかったので、その基となっている思想というか言語仕様ではない部分で色々と面白く感じる部分が多かったです。特に記憶に残るのは CoC (Convention over Configuration) といわれる「設定より規約を」という思想で、日頃 .NET に触れている自分としては、プロパティや属性、オプション指定などで動作を指定することになれているので、「デフォルトの設定」を主に扱うという考え方はかなり新鮮でした。

CLR/H #56 2011/03/26

今回は IDE など開発環境についてはほとんど触れられず、基本シェルを利用しての解説だったというのも最近行っていなかったため非常に新鮮。最近出た Razor 同様簡易な記述を行える Slim もなかなか面白いと思います。

P3260445s

ただ自分の基礎知識が不足していたのがあり、当日色々なコードを目にしてもなかなかピンとこなかったりしたのが残念。次があれば、もっと勉強してから参加するとさらに面白さが増すだろうな、と感じました。

おやつタイム

恒例のおやつタイム。今回は・・・

CLR/H #56 2011/03/26

CLR/H #56 2011/03/26

@yumehara さんによる差し入れケーキもあってかなりゴージャスでしたw

ライトニングトーク

今回は 3 名によるライトニングトークが行われました。

1:Ruby 向け multiset ライブラリのご紹介 ( @h_hiro_ さん ) [スライド]

CLR/H #56 2011/03/26

今回は Rails デイというのもあり自作の多重集合ライブラリな mutilset ライブラリの紹介でした。ライブラリの利用により、今までよりもさらにスッキリとしたコードで記述出来る点はかなりわかりやすかったです。また実際の利用方法が非常にわかりやすい説明で・・・w 集計処理などで、一つのキーに対して複数の値をもてる、というのはなかなかイメージしにくいかと思いますが、そのあたりを非常にわかりやすい例を持ち出して説明されていたのがすごかったと思います。.NET ではこういうライブラリあるのかな、と気になりました。

2:Small Basic を実務で使ってみませんか ( @jsakamoto さん )

CLR/H #56 2011/03/26

CLR/H で LT といえばこの人 @jsakamoto さん。今回は以前の勉強会で扱われたSmallBasicを実際の業務で利用してみよう、という内容でした。元々 Small Basic 自体、たいしたことができないイメージを持たれているけど、web からのデータ取得やテキストファイルの読み書き、.NET のライブラリをコールできるなど、使ってみると色々な事ができるということでした。また IDE が非常にシンプルかつわかりやすいものであるので、IT Pro など非開発者にとっても触りやすいというのがメリットというのはかなり共感しました。CodePrex で拡張ライブラリを公開されているのでこれも興味が湧きます。

3:WindowsPhone 7 ユーザーが今出来ること ( @mentaro さん )

CLR/H #56 2011/03/26

CLR/H で LT といえばこの人(※ただし裏) @mentaro さん。今回は・・・ターゲットは 30 代リア充である Windows Phone 7。しかし昨今の事情が、アイデンティティーの崩壊ともいえる程の事態を発生させていた・・・!

もう言葉でどうまとめろというのか非常に難しいw 
「大丈夫じゃない、大問題だ」
→「これは Windows Phone 7 ユーザーのアイデンティティが失われる危機」
→→「挨拶できるよ!」「友達できるよ!」
→→→「解決!」

CLR/H #56 2011/03/26

実際に何があったのかは、ちょうどよくピンボケした写真があったので、ここからご想像くださいw

2011年3月23日水曜日

Windows XP での SIlverlight 4 で NetworkAddressChanged イベントが発生しない

しません(キリッ
簡単なロジックを作って調べてみたところ、ネットワークが無効な状態に変化しても NetworkAddressChanged イベントが発生しませんでした。
対策としては定期的に NetworkInterface.GetIsNetworkAvailable プロパティをチェックしてオンライン・オフラインを判定することになるんだろうけど・・・。

追記:
Microsoft Connect にフィードバックとして投稿しました。検索したところ同様の内容が発見できなかったのでやってみたのですが、これで過去に投稿済みとかだったら恥ずかしいですわぁw

https://connect.microsoft.com/VisualStudioJapan/feedback/details/652962/windows-xp-silverlight4-networkaddresschanged

2011年3月10日木曜日

Code Receipe に投稿してみました

MSDN でCode Receipe というのが今までコードサンプル集としてありがたかったんだけど、今回一般ユーザーからのコードサンプル投稿が可能になった、ということで一つ投稿してみました。

Workflow Foundation による別アプリケーション実行アクティビティのサンプル

個人的に大好きな Workflow Foundation で Activity をカスタマイズするサンプルです。ニッチすぎて、Code Receipe のトップページでは表示されないカテゴリである WF・・・

そのうち他のアクティビティカスタマイズサンプルや、.NET 4 でのカスタマイズサンプルなんかも投稿してみようかな。

2011年3月8日火曜日

BPOS を触ってみている (2)

Internet Explorer 6 以降とそれ以外のブラウザでは利用できる Outlook Web Access の機能に結構違いがあるので比較としてスクリーンショットをペタっと。

OWA_IE9

これが Internet Explorer 9 での画面。これがOWAでのフル機能バージョン。

OWA_CHROME

そしてこれが Chrome での画面。比べてもらうとわかるけど、結構機能削減というか見た目をおとなしくしているんだよね。予定表は 1 日分の表示しかできないとか。

ただとある方から、BPOS の後継である Office 365 では、FirefoxやSafariでも同じように RIA できる、との情報をいただいているので、IE以外を利用されている方はもう少し待てばよしとのことです。

2011年3月7日月曜日

BPOS を触ってみている・・・

下記のリンク先で3月いっぱいでキャンペーンを行っているのを見たので、今まで触っていた内容+αをまとめてみました。

マイクロソフトのクラウドサービス使ってブログに書こうキャンペーン - ブログに書くだけで、Amazon ギフト券がもらえる | 購入方法 (購入情報) | Microsoft Online Services

今の会社は Microsoft のパートナー(サブスクリプションパートナーだけど)なので、BPOSのライセンスがあるんだけど、自分以外触ろうとする人がいないので、一人でBPOSを触ってみた。さ、さみしくなんかないですYo!

・・・実はアカウント開設自体は去年の初夏の頃だったんだけど、その後色々忙しくなったこと、そして「管理パスワードを紛失」した事もあって、しばらく触っていなかったんだよね。

ただこれでは勿体ないということで、去年の年末あたりにサポートに問い合わせ、というかサポートサイトにオンラインでヘルプを書き込み。その後、電話がかかってきて親切丁寧に対応していただき、無事にパスワードを初期化してもらって今に至ります。この時の対応は本当に丁寧で助かりました。これはもっと褒められてもいいと思いますw

まずは一番利用しやすいメール周り。Outlook Web Access という形でブラウザ上からも利用できるのは便利。見た目も Outlook なので人によってはかなりいいんじゃないかな。ただ、Internet Explorer 6 以降でなければ Light モードという機能限定盤でしか動作「させない」というのは、今のご時世でどうしたもんだろうかと思った。一応自分も開発者なので、気持ちは分かるけど・・・。できれば Firefox、Chrome、Safari くらいはなんとか対応してほしいなぁ。

それとこれも日本固有の話題で仕方ないのは理解できるけど非常に残念なのは、俗に言うガラケーに未対応というところ。「レイアウトが崩れます~」という程度だったらまだいいんだけど、最初のログインサイトすらまともに表示されない。フルブラウザなら大丈夫なんだろうけど、パケット代の上限違うので試していなかったり・・・。最近はスマートフォンが増えているので恐らくは大丈夫だろうなぁ。どうしてもガラケーでと言う場合は、別途サードパーティの製品を利用する必要があるということで。

OWA-IE9

Internet Explorer 9 で接続した場合はこのような感じに。IE9でサクサク加減が増しているので、かなり使い心地は良いです。下手すると通常版(インストールしたもの)よりも・・・w

自分は基本的な使い方である、外出先からの「メールチェック」や「予定確認」を少しの間触っていたんだけど、ネット環境さえどうにかできるのであれば非常に便利。社内においても Outlook をアンインストールしてもいいんじゃないか、と思える。それぐらい便利。今後モバイルネットワークは一般的になると思われるので、通信環境はきっと時間が解決してくれそう。そうなった時に、このどこにいてもメールや予定を確認できるというのは凄く便利すぎると思えるねぇ。これって単純な事なんだけど効果がとても大きい。

職種にもよるけど、自分の机でなければできないと思っていた作業が、外出中でも可能になるのは正直素晴らしい。電車で移動中とか待ち合わせの時間待ちとか、ちょっとした空白の時間というのは結構発生するので、こういった時間を無駄にしなくて済むというのは自分にとってかなりいい感じ。

もちろんやる気がないときは絶対見ませんがw

とりあえず Exchange Online は軽く触ってみたので、また時間を作って SharePoint Online や Office Live Meeting や Communication Online も触ってみようかな・・・Communication 系は一人だとさびしすぎてダメかも知れませんが・・・。