2011-05-09 24 views
5

Tôi gặp sự cố khi xác thực để hoạt động bình thường trong nhà thiết kế cho hoạt động tùy chỉnh của tôi. Các mẫu đơn giản nhất để tái tạo hành vi này là như sau:Xác thực đối số trong nhà thiết kế hoạt động tùy chỉnh

Tôi có một WF4 hoạt động tùy chỉnh với một bộ sưu tập năng động của các đối số được lưu trữ trong một cuốn từ điển:

[Designer(typeof(DictionaryActivityDesigner))] 
public class DictionaryActivity : NativeActivity 
{ 
    [Browsable(false)] 
    public Dictionary<string, InArgument> Arguments { get; set; } 
    public InArgument<string> StringArg { get; set; } 

    public DictionaryActivity() 
    { 
     Arguments = new Dictionary<string, InArgument>(); 
    } 

    protected override void Execute(NativeActivityContext context) 
    { } 
} 

Trong thiết kế tôi dinamically tạo hộp văn bản biểu để chỉnh sửa những lập luận này. Người sử dụng có khả năng xác định các đối số và các loại của họ trong một cửa sổ modal riêng biệt, nhưng vì lợi ích của đơn giản tôi đã cố định các đối số trong mẫu này:

public partial class DictionaryActivityDesigner 
{ 
    private Dictionary<string, Type> definition; 

    public DictionaryActivityDesigner() 
    { 
     definition = new Dictionary<string, Type> 
     { 
      { "String Arg", typeof(string) }, 
      { "Int Arg", typeof(int) } 
     }; 

     InitializeComponent(); 
    } 

    public void InitializeGrid(Dictionary<string, Type> arguments) 
    { 
     ArgumentsGrid.RowDefinitions.Clear(); 
     ArgumentsGrid.Children.Clear(); 

     int gridRow = 0; 
     foreach (var arg in arguments) 
     { 
      ArgumentsGrid.RowDefinitions.Add(new RowDefinition()); 

      var label = new Label() 
      { 
       Content = arg.Key + ":" 
      }; 
      Grid.SetRow(label, gridRow); 
      Grid.SetColumn(label, 0); 
      ArgumentsGrid.Children.Add(label); 

      var textbox = new ExpressionTextBox() 
      { 
       ExpressionType = arg.Value, 
       OwnerActivity = ModelItem, 
       UseLocationExpression = false 
      }; 
      var binding = new Binding() 
      { 
       Mode = BindingMode.TwoWay, 
       Converter = new ArgumentToExpressionConverter(), 
       ConverterParameter = "In", 
       Path = new PropertyPath("ModelItem.Arguments[(0)]", arg.Key) 
      }; 
      textbox.SetBinding(ExpressionTextBox.ExpressionProperty, binding); 
      Grid.SetRow(textbox, gridRow); 
      Grid.SetColumn(textbox, 1); 
      ArgumentsGrid.Children.Add(textbox); 

      gridRow++; 
     } 
    } 

    private void ActivityDesigner_Loaded(object sender, RoutedEventArgs e) 
    { 
     InitializeGrid(definition); 
    } 
} 

Dưới đây là XAML cho các nhà thiết kế:

<sap:ActivityDesigner x:Class="ActivityValidation.DictionaryActivityDesigner" 
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:s="clr-namespace:System;assembly=mscorlib" 
         xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation" 
         xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation" 
         xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation" 
         Loaded="ActivityDesigner_Loaded"> 
    <sap:ActivityDesigner.Resources> 
     <ResourceDictionary> 
      <sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" /> 
     </ResourceDictionary> 
    </sap:ActivityDesigner.Resources> 
    <StackPanel Orientation="Vertical"> 
     <Grid Name="ArgumentsGrid"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition/> 
       <ColumnDefinition MinWidth="250" /> 
      </Grid.ColumnDefinitions> 
     </Grid> 
     <sapv:ExpressionTextBox ExpressionType="s:String" 
           OwnerActivity="{Binding ModelItem}" 
           Expression="{Binding ModelItem.StringArg, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In}" /> 
    </StackPanel> 
</sap:ActivityDesigner> 

Phương thức InitializeGrid thêm hộp văn bản biểu thức cho đối số vào ArgumentGrid. Theo đó, tôi có một hộp văn bản biểu thức được định nghĩa tĩnh riêng biệt cho một đối số cố định trong hoạt động để chứng minh hành vi mong muốn (gần như).

Bây giờ cho các vấn đề:

  1. biểu thức không hợp lệ cho các đối số động chỉ gây ra các biểu tượng lỗi xuất hiện bên cạnh hộp văn bản nhưng nó không tuyên truyền để thanh trên cùng của các nhà thiết kế như nó nếu có một lỗi trong hộp văn bản được xác định tĩnh.

  2. Nếu tôi đóng thiết kế ở trạng thái không hợp lệ như vậy (và lưu định nghĩa), biểu tượng eror sẽ truyền chính xác đến thanh trên cùng ngay cả khi lỗi chỉ trong hộp văn bản động. Mặc dù hành vi trở nên kỳ lạ hơn sau đó. Sau khi thay đổi các giá trị cho các đối số, bây giờ ngay cả biểu tượng lỗi bên cạnh hộp văn bản không hoạt động liên tục nữa.

  3. Nếu tôi xóa các nội dung của một hộp văn bản động hoàn toàn, giá trị trong từ điển được thiết lập để null mà biểu hiện trong định nghĩa workflow như <x:Null x:Key="String Arg" /> thay vì <InArgument x:TypeArguments="x:String" x:Key="String Arg">["a"]</InArgument> hoặc chỉ ommiting mục như trường hợp trước khi chỉnh sửa biểu thức lần đầu tiên. Nếu tôi mở lại một luồng công việc như vậy ngay cả hộp văn bản được tạo tĩnh không hoạt động chính xác nữa (biểu tượng lỗi chỉ hiển thị khi hộp văn bản được tập trung và nó không lan truyền lên đầu nữa).

Có vẻ như tôi đang làm điều gì đó sai khi tạo hộp văn bản động. Điều gì sẽ là cách chính xác để làm điều đó? Có ví dụ nào để tạo nhà thiết kế cho hoạt động tùy chỉnh với số đối số động không?

EDIT:

Đối với những người quan tâm:

+0

Chờ, bạn có đang xác thực mọi cuộc gọi đến CacheMetadata không? Đó là về nơi duy nhất bạn có thể thực hiện xác thực trên Hoạt động của mình và có các lỗi/cảnh báo được truyền bá quy trình làm việc. – Will

+0

@Tôi có thể thêm lỗi xác thực và cảnh báo trong CacheMetadata, nhưng ExpressionTextBox có xác thực được tích hợp riêng của nó hiển thị biểu tượng lỗi bên cạnh hộp văn bản nếu biểu thức đã nhập không hợp lệ. Tôi sẽ không muốn thực hiện lại việc xác thực đó và tôi không biết làm thế nào tôi có thể truy cập chức năng xác nhận hợp lệ đó từ bên trong CacheMetadata để tự truyền nó bằng cách thêm một lỗi xác nhận hợp lệ. Ngoài ra: tuyên truyền dường như làm việc tốt miễn là tôi tránh các bộ sưu tập các đối số. –

Trả lời

4

Tôi gặp sự cố tôi đã mô tả ở đây trong khi cố gắng tạo nhà thiết kế cho bộ sưu tập đối số động trong một hoạt động.Tôi đã cố gắng giải quyết vấn đề bằng cách sử dụng cửa sổ được xây dựng trong DynamicArgumentDialog. Tôi đã phải cơ cấu lại hoạt động của tôi để chấp nhận một bộ sưu tập duy nhất của cả hai đối số đầu vào và đầu ra:

public Dictionary<string, Argument> Arguments { get; set; } 

thay vì hai bộ sưu tập riêng tôi đã sử dụng trước đây:

public Dictionary<string, InArgument> InArguments { get; set; } 
public Dictionary<string, OutArgument> OutArguments { get; set; } 

Tôi tìm thấy Custom Activity to Invoke XAML Based Child Workflows rất hữu ích khi thực hiện công việc này.

Các vấn đề liên quan