WF4 – Xây dựng custom activities (Phần 2)

Ở phần trước, chúng ta đã tìm hiểu cách xây dựng các custom activities đơn giản. Tuy nhiên, nếu để ý chúng ta sẽ thấy rằng, các custom activities này nếu sử dụng ở môi trường designer sẽ trở nên khó khăn vì gần như không thể tương tác với các custom activities này giống như việc tương tác với các activities được xây dựng sẵn.

WF4 vẫn hỗ trợ chúng ta xây dựng các custom activities cùng designer giúp cho việc sử dụng các custom activities dễ dàng hơn. Trong bài viết này, chúng ta sẽ xây dựng Email acitivity cùng với việc xây dựng designer cho custom activity này.

Để có thể bắt đầu xây dựng designer cho một custom activity, bước đầu chúng ta phải xây dựng custom activity bằng code giống như các ví dụ trước chúng ta đã làm.

Code Snippet
  1. public sealed class EmailActivity : CodeActivity
  2. {
  3.     [RequiredArgument]
  4.     public InArgument<string> To { get; set; }
  5.     public InArgument<string> CC { get; set; }
  6.     public InArgument<string> BCC { get; set; }
  7.     [RequiredArgument]
  8.     public InArgument<string> Subject { get; set; }
  9.     [RequiredArgument]
  10.     public InArgument<string> Body { get; set; }
  11.  
  12.     protected override void Execute(CodeActivityContext context)
  13.     {
  14.         // implements send email logic code here
  15.  
  16.         // for visualizing the result of sending email
  17.         // writes something to console
  18.         Console.WriteLine("To:      {0}", context.GetValue(To));
  19.         Console.WriteLine("CC:      {0}", context.GetValue(CC));
  20.         Console.WriteLine("BCC:     {0}", context.GetValue(BCC));
  21.         Console.WriteLine("Subject: {0}", context.GetValue(Subject));
  22.     }
  23. }

Sau khi đã hoàn tất việc xây dựng logic code cho custom activity, chúng ta tiếp tục thêm vào 1 Activity Designer cho project.

image

Tuy nhiên, chúng ta để ý thấy rằng tên class giữa custom activity và activity designer (cụ thể ở đây là EmailActivity và EmailActivityDesigner) là khác nhau. Do đó, để có thể quy định rằng designer này thuộc về một custom designer, chúng ta cần phải thêm vào một attribute cho class EmailActivity như sau

Code Snippet
  1. [Designer(typeof(EmailActivityDesigner))]
  2. public sealed class EmailActivity : CodeActivity

Tiếp theo và việc xây dựng designer cho EmailActivity. Ở đây, chúng ta sẽ đi qua chi tiết việc xây dựng đối với field To

Việc sử dụng XAML đã mang lại cho WF4 rất nhiều lợi ích, và một trong những lợi ích đó là đem lại các tính năng như Data Binding trong việc xây dựng giao diện thể hiện trực quan các thông tin, dữ liệu của activity. Ở đây, đối với field To, chúng ta sẽ bao gồm 1 TextBlock và 1 TextBox cho phép nhập vào giá trị. Tuy nhiên, qua các ví dụ trong các bài viết trước, chúng ta để ý rằng các textbox trong các activity của chúng ta không chỉ đơn thuần là nhập vào một string, mà nó còn cho phép chúng nhập vào một expression từ đơn giản đến phức tạp. Do đó, chúng ta sẽ thay thế TextBox của chúng ta bằng 1 control khác là ExpressionTextBox và kết qua thu được như sau:

Code Snippet
  1. <StackPanel>
  2.     <TextBlock Text="To" Margin="4,4,4,0"/>
  3.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  4.           HintText="Enter To emails"/>
  5. </StackPanel>

image

Tiếp đến, chúng ta tiếp tục thực hiện việc binding dữ liệu (kỹ thuật hoàn toàn giống với WPF). Tuy nhiên, có một điểm cần chú ý ở đây là do giữa class logic và class designer là 2 class hoàn toàn tách biệt nhưng chúng ta  muốn binding từ designer vào các properties trong class logic và ngược lại nên chúng ta sẽ thông qua một đối tượng là ModelItem (sẽ trình bày chi tiết về đối tượng này ở các bài viết sau).

Code Snippet
  1. <TextBlock Text="To" Margin="4,4,4,0"/>
  2. <sapv:ExpressionTextBox Margin="4,0,4,4"
  3.     OwnerActivity="{Binding ModelItem}"
  4.     HintText="Enter To emails"
  5.     ExpressionType="s:String"
  6.     Expression="{Binding Path=ModelItem.To, Mode=TwoWay,
  7.                  Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  8.                  ConverterParameter=In}"/>

Chú ý: Do control ExpressionTextBox sẽ trả về một đối tượng là Expression và property To lại là InArgument nên trong quá trình binding chúng ta cần cung cấp 1 converter để thực hiện việc chuyển đổi qua lại giữa 2 kiểu dữ liệu này.

Chú ý: Ở đây chúng ta sẽ quy định thêm một property nữa cho ExpressionTextBlock là ExpressionType.

Tiếp tục thực hiện tương tự đối với các properties còn lại và kết quả cuối cùng như sau:

Code Snippet
  1. <sap:ActivityDesigner.Resources>
  2.     <sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter"/>
  3. </sap:ActivityDesigner.Resources>
  4. <StackPanel>
  5.     <TextBlock Text="To" Margin="4,4,4,0"/>
  6.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  7.         OwnerActivity="{Binding ModelItem}"
  8.         HintText="Enter To emails"
  9.         ExpressionType="s:String"
  10.         Expression="{Binding Path=ModelItem.To, Mode=TwoWay,
  11.                      Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  12.                      ConverterParameter=In}"/>
  13.     <TextBlock Text="CC" Margin="4,4,4,0"/>
  14.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  15.         OwnerActivity="{Binding ModelItem}"
  16.         HintText="Enter CC emails"
  17.         ExpressionType="s:String"
  18.         Expression="{Binding Path=ModelItem.CC, Mode=TwoWay,
  19.                      Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  20.                      ConverterParameter=In}"/>
  21.     <TextBlock Text="BCC" Margin="4,4,4,0"/>
  22.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  23.         OwnerActivity="{Binding ModelItem}"                                
  24.         HintText="Enter BCC emails"
  25.         ExpressionType="s:String"
  26.         Expression="{Binding Path=ModelItem.BCC, Mode=TwoWay,
  27.                      Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  28.                      ConverterParameter=In}"/>
  29.     <TextBlock Text="Subject" Margin="4,4,4,0"/>
  30.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  31.         OwnerActivity="{Binding ModelItem}"
  32.         HintText="Enter Subject"
  33.         ExpressionType="s:String"
  34.         Expression="{Binding Path=ModelItem.Subject, Mode=TwoWay,
  35.                      Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  36.                      ConverterParameter=In}"/>
  37.     <TextBlock Text="Body" Margin="4,4,4,0"/>
  38.     <sapv:ExpressionTextBox Margin="4,0,4,4"
  39.         OwnerActivity="{Binding ModelItem}"
  40.         HintText="Enter email body"
  41.         ExpressionType="s:String"
  42.         Expression="{Binding Path=ModelItem.Body, Mode=TwoWay,
  43.                      Converter={StaticResource ResourceKey=ArgumentToExpressionConverter},
  44.                      ConverterParameter=In}"/>
  45. </StackPanel>

image

Sau khi đã xây dựng xong, tiến hành compile project và tạo một workflow mới để kiểm tra EmailActivity này

image

Và kết quả thu được như sau

image

Published 08-04-2010 2:39 PM by Duy Nguyen
Filed under: , ,
Powered by Community Server (Non-Commercial Edition), by Telligent Systems