2011年4月13日水曜日

ActivityDesigner でコンボボックス

ActivityDesigner を使ってカスタムアクティビティを作成する際、コンボボックスで値を指定したくなることが多々あります。通常の文字とか数字とかでしたら、ExpressionTextBox でそのまま入力するだけでも構わないのですが、内容によっては特定の選択肢に限定したい場合がどうしても出てきます。

このような場合、Activity と ActivityDesigner だけでは不足で、通常ユーザーコントロールを作成する場合にも用いる TypeConverter 的なものを用意する必要があります。実際には IValueConverter インターフェースを継承したクラスです。

  1: Imports System.Activities
  2: Imports System.Windows.Data
  3: Imports System.Activities.Presentation.Model
  4: Imports Microsoft.VisualBasic.Activities
  5: Imports System.Activities.Expressions
  6: Imports System.Windows.Controls
  7: 
  8: Public Class ComboBoxItemConverter
  9:     Implements IValueConverter
 10: 
 11:     Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
 12: 
 13:         Dim mItem = CType(value, ModelItem)
 14:         If mItem IsNot Nothing Then
 15:             Dim inArgs = TryCast(mItem.GetCurrentValue, InArgument(Of String))
 16:             If inArgs IsNot Nothing Then
 17:                 Dim expr = inArgs.Expression
 18:                 Dim liter = TryCast(expr, Literal(Of String))
 19:                 If liter IsNot Nothing Then Return "\" + liter.Value + "\"
 20: 
 21:                 Dim vbExpr = CType(expr, VisualBasicValue(Of String))
 22:                 If vbExpr IsNot Nothing Then Return vbExpr.ExpressionText
 23: 
 24:             End If
 25:         End If
 26:         Return Nothing
 27:     End Function
 28: 
 29:     Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
 30: 
 31:         Dim itemCount = CType(DirectCast(value, ComboBoxItem).Content, String)
 32:         Dim vbArgs As New VisualBasicValue(Of String)(itemCount)
 33:         Dim inArgs As New InArgument(Of String)(vbArgs)
 34:         Return inArgs
 35: 
 36:     End Function
 37: End Class
 38: 


ロジックとしてはこのような形になります。Convert メソッドはアクティビティの値を別のものに変換するロジックを、ConvertBack メソッドはデザイナ上の値をアクティビティの値に変換するロジックとなります。



これを準備した上で、上記 Conber t用クラスを xaml 上にてリソースに定義します。



  1: <sad:ActivityDesigner.Resources>
  2:     <ResourceDictionary>
  3:         <c:ComboBoxItemConverter x:Key="comboBoxItemConverter"/>
  4:     </ResourceDictionary>
  5: </sad:ActivityDesigner.Resources>


このような形で定義した上でデザイナ上の要素を記述します。



  1: <ComboBox SelectedValue="{Binding Path=ModelItem.TargetType, Mode=TwoWay, Converter={StaticResource comboBoxItemConverter}}"   Name="comboBox1" ItemsSource="{Binding}">
  2:     <ComboBoxItem>SQL Server</ComboBoxItem>
  3:     <ComboBoxItem>OLE DB</ComboBoxItem>
  4: </ComboBox>
  5: 


このようにコンボボックスの SelectedValue プロパティに対して、Converter を利用するように記述します。後はアクティビティ側でこれらを定義したデザイナを利用するように System.ComponentModel.Designer 属性を用いて設定します。



WF4-1



実際の利用イメージは上記のようになります。アクティビティデザイナ上で定義しているので、ワークフローデザイナ上で直接入力可能になっているのがわかると思います。

0 件のコメント:

コメントを投稿