2011-10-07 23 views
0

我有一個很難得到我的一個自定義的活動設計器中的工作流設計器以顯示。我的活動包括活動FUNC,我已經發現了一些與他們打交道herehereherehere博客帖子。綁定錯誤<>

自定義活動具有ActivityFunc<>作爲輸入參數,並且我需要以暴露在FUNC設計者作爲其中用戶可以將一個「內」活性(點菜TransactionScope)放置區。

定製活動創作的XAML和FUNC的聲明是這樣的:

<x:Property Name="CompletionTest" Type="ActivityFunc(sdscmt:DmeTask, sdsav:WfPatient, sdscmc:DmeClinicalElement, x:Boolean)" /> 

的XAML還包含一個InvokeFunc<>活動相匹配的CompletionTest財產。

活動設計遵循上述mentionned的博客文章中概述的建議。特別是,它會覆蓋OnModelItemChanged初始化CompletionTest屬性:

if (this.ModelItem.Properties["CompletionTest"].Value == null) 
{ 
    this.ModelItem.Properties["CompletionTest"].SetValue(
     new ActivityFunc<DmeTask, WfPatient, DmeClinicalElement, bool>() 
     { 
      Argument1 = new DelegateInArgument<DmeTask> 
      { 
       Name = "task" 
      }, 
      Argument2 = new DelegateInArgument<WfPatient> 
      { 
       Name = "patient" 
      }, 
      Argument3 = new DelegateInArgument<DmeClinicalElement> 
      { 
       Name = "element" 
      }, 
      Result = new DelegateOutArgument<bool> 
      { 
       Name = "success" 
      }, 
     }); 
} 

設計師的XAML看起來像這樣:

<sap:ActivityDesigner x:Class="SoftInfo.Dme.ServicesDme.Workflow.Design.PerformTaskDesigner" ... > 
    <StackPanel> 
     <sap:WorkflowItemPresenter AllowedItemType="{x:Type sa:Activity}" Background="Transparent" MinWidth="150" MinHeight="100" HintText="Drop the completion test here" Margin="5,5,5,5" Item="{Binding Path=ModelItem.CompletionTest.Handler, Mode=TwoWay}" /> 
    </StackPanel> 
</sap:ActivityDesigner> 

這一切後,每當我把我的自定義活動的一個實例到工作流,我會看到一個標有「無法爲PerformTask生成視圖」的紅色框,我的設計者應該出現在該框中。盒子的工具提示表明設計師發生了異常:

System.Windows.Markup.XamlParseException: A 'Binding' cannot be set on the 'Item' property of type 'WorkflowItemPresenter'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject. 

我不明白我在做什麼錯。我以前多次使用過WorkflowItemPresenter,這是我第一次得到這個綁定錯誤。

回答

0

這類型的搞砸的路要走這一點。錯誤可能不正確;內在的例外會告訴我會下注的故事(對不起,我今天工作時聽着權力的遊戲)。這裏

public sealed class MyActivity: NativeActivity, IActivityTemplateFactory 
{ 
    public const string ChildArgumentName = "theArgument"; 

    public ActivityFunc<object, bool> Child { get; set; } 

    Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target) 
    { 
     return new MyActivity() 
     { 
      Child = new ActivityFunc<Capture, bool> 
      { 
       Argument = new DelegateInArgument<object>(ChildArgumentName) 
      } 
     }; 
    } 
} 

注意兩件事情:

我實現IActivityTemplateFactory配置我的活動委託。是的,設計圖面將實例化一個Activity的實例,僅用它來創建同一個Activity的另一個實例(當然是正確配置),但是這種方法是防彈的。如果需求決定,你可以在其他地方將你的IATF實施移到其他地方,但是如果沒有關係誰在乎呢?

請注意,我在我的活動設計聲明函數功能的參數的名稱將是什麼。你可以用更通用的方式(自定義屬性等)來做到這一點,但如果你的活動以可預見的方式組合在一起,我發現這是自動將孩子活動與父母聯繫起來的最簡單方式。因人而異。

在設計,它類似於:

<sap:WorkflowItemPresenter 
    HintText="Add child here" 
    Item="{Binding ModelItem.Child.Handler}" /> 

這就是你需要的。如果活動的簽名不匹配,則不適合。孩子也需要IATF的優勢,把自己綁定到它的父:

public sealed class ChildActivity : NativeActivity<bool>, IActivityTemplateFactory 
{ 
    public InArgument<object> Target { get; set; } 

    Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target) 
    { 
     return new ChildActivity 
     { 
      Target = new VisualBasicValue<object>(MyActivity.ChildArgumentName) 
     }; 
    } 
} 

如果你希望你的孩子的活動在不同的目標被丟棄,你可能需要做targetDependencyObject的一些惱人的檢查,這將使您檢查當前的工作流程樹。 (請注意,我並不是100%熟悉VisualBasicValue的隱式轉換行爲,因此您可能會在上面的代碼中遇到一些編譯器錯誤!)

另一個選項,如果您必須特別棘手(將一個Activity從工具箱,然後將其拖到其他地方,您將不得不重新進行檢查)是從CacheMetadata內檢查工作流的當前狀態。我沒有這樣做,但我相信你可以更新註冊與設計界面,以反映當前的工作流程狀態。

+0

謝謝。我熟悉'IActivityTemplateFactory',但沒有在我的問題中提到它,因爲無論我的自定義活動是否實現它,我都會得到相同的錯誤。我的實現類似於上面的'MyActivity'示例。 –

相關問題