ラベル WPF の投稿を表示しています。 すべての投稿を表示
ラベル WPF の投稿を表示しています。 すべての投稿を表示

2013年12月14日土曜日

WF における xaml について簡単な説明をしてみる

Workflow Foundation も xaml を利用しているので XAML Advent Calendar 2013 に参加してみました。他の方々に比べると異様な感じを醸し出しているのですが、まあ諦めてください。

まず Workflow Foundation での xaml ですが、2つの使われる場面があります。一つは、アクティビティデザイナーで利用するデザイナーの定義。もう一つはワークフロー自体の定義になります。

2011年12月9日金曜日

VB の xaml と C# の xaml

※これは VB Advent Calendat 2011 用の投稿です

ネット上で調べ物をしていると C# で書かれている記事に出会う事が多々あると思います。基本的なロジックは、コード変換を行っているサービスを利用するなど C# を知らない人でもどうにかする方法が用意されています。ですがコードだけではなくxaml 上でも C# と VB では違いがあります。

2011年11月9日水曜日

属性指定から IRegisterMetadata.Register へ

前回の LocBAML を利用した記事にあるように、現在拙作の WFDesignerExpress を多言語対応(といっても機械翻訳での対応ですが……)を行っています。その際に非常に感じたのは、クラスやプロパティに対して属性を設定するのではなく、IRegisterMetadata.Register メソッドにて属性の設定を行うようにするのが、WPF や WF でのプログラミングを行う際に適している、というところです。

2011年11月7日月曜日

.NET 4 における LocBAML を利用した多言語対応

アプリケーションの多言語化対応というのは、人によっては必要な作業だと思います。MSDN でもローカライズ関係の資料が色々と掲載されており、その中の一つの方法として LocBaml ツールを利用したローカライズがあります。

2011年11月6日日曜日

InArgument(T) から String への変換

アクティビティを色々作成している中で、次のようなケースがありました。

  • デザイナ上で指定した画像のイメージをデザイナ上にプレビュー表示する

アクティビティのプロパティとしてファイル名を受け取るとして、そのファイル名で指定された画像をデザイナ上でプレビュー表示をする、というものです。その際にプロパティが String で指定されているのであればまだ簡単なのですが、アクティビティの場合ほとんどのプロパティは InArgument(T) を指定することもあり、値の変換には少し方法を変える必要があります。

2011年11月2日水曜日

MessageBoxIcon の値を IValueConverter で変換

メッセージボックスを表示するアクティビティを作っていて、デザイナ上でアイコンやボタンの設定をラジオボタンにて選択させようとした時、MessageBoxIcon 列挙値を変換するような IValueConverter を用意してあげれば、ラジオボタンにバインドができて非常に楽になります。ただし、その際に少しだけ注意する点がありました。

2011年4月14日木曜日

Activity のプロパティダイアログで[ファイルを開く]ダイアログの表示

元ネタは海外の BBS から。ファイル名を指定するようなアクティビティを作ろうとした場合、やはり [ファイルを開く] ダイアログを利用して指定させたいというのはあると思います。そのような場合には以下のような感じで実装します。

・DialogPropertyValueEditor を継承したクラスを用意する

  1: Imports System.Activities
  2: Imports System.Activities.Presentation
  3: Imports System.Windows.Forms
  4: 
  5: Public Class FileBrowserDialogPropertyValueEditor
  6:     Inherits PropertyEditing.DialogPropertyValueEditor
  7: 
  8:     Private _res As New ExecuteOtherWorkflowActivityDesigner
  9: 
 10:     Public Sub New()
 11:         Me.InlineEditorTemplate = TryCast(_res.Resources("FileBrowserInlineEditorTemplate"), DataTemplate)
 12:     End Sub
 13: 
 14:     Public Overrides Sub ShowDialog(ByVal propertyValue As System.Activities.Presentation.PropertyEditing.PropertyValue, ByVal commandSource As System.Windows.IInputElement)
 15: 
 16:         Using dlg As New OpenFileDialog
 17:             With dlg
 18:                 .AddExtension = True
 19:                 .CheckFileExists = True
 20:                 .Multiselect = False
 21:                 .Filter = "ワークフロー(*.xaml)|*.xaml|全てのファイル(*.*)|*.*"
 22: 
 23:                 If .ShowDialog = DialogResult.OK Then
 24:                     propertyValue.StringValue = dlg.FileName
 25:                 End If
 26:             End With
 27:         End Using
 28: 
 29:     End Sub
 30: 
 31: End Class


このクラスはプロパティダイアログ上での入力時にどのような挙動をさせるかを記述するクラスとなっています。コンストラクタで、InlineEditorTemplate プロパティに何やら DataTemplate を設定していますが、これがプロパティダイアログ上で表示されるものとなります。今回は面倒だったので、アクティビティで利用するデザイナ上に定義したものを呼び出していますw



  1: <DataTemplate x:Uid="DataTemplate_1" x:Key="FileBrowserInlineEditorTemplate">
  2:     <Border x:Uid="Border_1" BorderThickness ="1">
  3:         <Grid>
  4:             <Grid.ColumnDefinitions>
  5:                 <ColumnDefinition Width="1*"/>
  6:                 <ColumnDefinition Width="Auto"/>
  7:             </Grid.ColumnDefinitions>
  8:             <TextBox Grid.Column="0" Text="{Binding StringValue}"/>
  9:             <sapp:EditModeSwitchButton Grid.Column="1"/>
 10:         </Grid>
 11:     </Border>
 12: </DataTemplate>
 13: 


そのテンプレートの内容はこのような感じにしてあります。テキストボックスはそのままとして EditModeSwitchButton が [...] ボタンの表示を行います。余談ですがこのテンプレートをアクティビティ側に適用した場合、何故か VS によく出てくるピンボタンに変化します。



・アクティビティの対象となるプロパティに Editor 属性を付加する



このように作成したクラスを対象となるプロパティに Editor 属性を利用して設定します。



  1: <Browsable(True)>
  2: <Editor(GetType(FileBrowserDialogPropertyValueEditor), GetType(DialogPropertyValueEditor))>
  3: Public Property WorkflowFile As String


このような感じで設定します。



このように実装したアクティビティを利用するとこのように表示されます。



fileDialog



WorkflowFile プロパティの欄にテキストボックスとボタンが表示されているのが見えると思います。このボタンをクリックすると [ファイルを開く] ダイアログが表示され、そこで選択したファイル名がプロパティの値として設定されるようになります。



このようにアクティビティのプロパティについては、プロパティダイアログ上での入力もカスタマイズできる手段が提供されています。

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



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

2011年4月8日金曜日

ActivityDesigner でのアイコン指定

よく参考にしている海外 MSDN ブログで見つけたものです。ActivityDesginer は XAML で作成するのでややわかりにくい部分があるのですが、プロパティの一覧を眺めていると大体想像できるかと思います。

  1: <sad:ActivityDesigner.Icon>
  2:     <DrawingBrush>
  3:         <DrawingBrush.Drawing>
  4:             <ImageDrawing ImageSource="pack://application:,,,/Images/commnet-out.png">
  5:                 <ImageDrawing.Rect>
  6:                     <Rect Location="0,0" Size="16,16" ></Rect>
  7:                 </ImageDrawing.Rect>
  8:             </ImageDrawing>
  9:         </DrawingBrush.Drawing>
 10:     </DrawingBrush>
 11: </sad:ActivityDesigner.Icon>


今回の例は同一ソリューションにビルドアクションを Resources として組み込んだ png 画像を設定した例です。ソリューションの構成としては、[ソリューション]直下に images と言う名前のフォルダを作成、その中に comment-out.png という画像ファイルを用意している形です。



参考にしていた Blog では書き方が若干異なりますが同一の意味合いとなります。