2012年2月2日木曜日

ValidationService.NavigateToError メソッドの挙動

ValidationService というワークフローの検証を行うサービスクラスがあります。何気なく MSDN のリファレンスを見ていると NavigateToError メソッドという
「作業画面で、アクティビティのエラーの場所にキーボード フォーカスを移動します。」
と書かれたものがあったので試してみたところ、ちょっと動きがおかしかったので記録として残しておきます。

メソッドとしては引数として id を渡すようになっており、パラメータの説明としても「エラー ID 番号」と書かれていたので、恐らく「エラーが発生しているアクティビティの ID 値を渡せば、そこを表示するようにデザインビューが変化する」と考えていました。

そこで次のようなロジックを作って試してみました。

   1: Dim resultID As String = ""
   2:  
   3: designer.Flush()
   4: Dim vsv = designer.Context.Services.GetService(Of ValidationService)()
   5: Dim rootActivity As Activity = Nothing
   6: 'ModelService を利用してルートアクティビティを取得
   7: Dim mdlService = designer.Context.Services.GetService(Of ModelService)()
   8: Dim debugTree = TryCast(mdlService.Root.GetCurrentValue(), IDebuggableWorkflowTree)
   9: If (debugTree IsNot Nothing) Then
  10:     rootActivity = debugTree.GetWorkflowRoot()
  11: Else
  12:     rootActivity = mdlService.Root.GetCurrentValue()
  13: End If
  14: '検証を行いエラー情報を取得
  15: Dim validError = ActivityValidationServices.Validate(rootActivity)
  16: If validError.Errors.Count > 0 Then resultID = validError.Errors(validError.Errors.Count - 1).Id
  17:  
  18: If resultID <> "" Then
  19:     Dim vsv = designer.Context.Services.GetService(Of ValidationService)()
  20:     vsv.NavigateToError(resultID)
  21: End If

一部抜粋なので分かりにくいかも知れませんが、designer とは WorkflowDesigner クラスのインスタンスで画面上のデザイナそのものです。Workflow Foundation では、この WorkflowDesigner から実行時のコンテキストを通して各種サービスを取得、利用します。今回の ValidationService も同様に取得します。

このロジックを試してみるために次のようなワークフローを用意しました。

ErrorWorkflow

Delay アクティビティと Assign アクティビティを交互に並べたもので、必須項目を何も入力していない状態にしています。フォーカスが遷移するのを把握するために、親アクティビティをカレントにしておきます。

NavigationStart

続いて検証ロジックを実行し、取得したエラー情報の中身を確認します。

ValidationError

今回は最後尾に存在しているエラー情報を元に NavigateToError メソッドを呼び出します。引き渡す ID 値は上記デバッグウィンドゥに表示されている 9 を渡します。

avigationEnd

するとなぜか別のアクティビティにフォーカスが遷移します・・・。

というように謎の挙動を見せてくれますが、使い方が悪いのか、実は不具合で WF4.5 で直るものなのか、そのあたりまでは確認が取れていません。

0 件のコメント:

コメントを投稿