将数据绑定到自定义活动设计器中的Combobox

时间:2010-04-27 19:27:32

标签: workflow workflow-foundation workflow-foundation-4

我有一个自定义活动,其中一个in参数是一个字符串。然而,我不希望设计者输入任意字符串,而是希望向设计者呈现带有选项列表的Combobox,这些选项是动态的,并且从数据库加载到List<>中。采集。

我的问题是我不知道如何将设计器中的Combobox绑定到此列表,并将选择设置为活动的in参数。在视觉上我让活动设计师工作,这只是一步。

3 个答案:

答案 0 :(得分:7)

通常情况下,我会使用property而不是InArgument来编写活动。这简化了方案:

<ComboBox ItemsSource="{Binding Path=ValidOptions}" 
 SelectedValue="{Binding Path=ModelItem.MyStringProperty, Mode=TwoWay}"/>

(此处ValidOptions是ActivityDesigner类的一些Collection属性.MyStringProperty是基础活动的一些公共get / set / property,例如:

public string MyStringProperty { get; set; }

如果将InArgument添加到混音中,您将遇到的问题是,无法将组合框中的字符串值直接分配给期望ModelItem的{​​{1}}。这可以使用绑定中的自定义InArgument<string>进行修复。

答案 1 :(得分:4)

以前的答案很有帮助,但对我来说还不够。最终,我在微软的.Net 4.5开发人员指南Binding a custom activity property to a designer control中找到了一篇很棒的文章。那篇文章几乎是完整的答案 - 除了自定义转换器类中的一个小错误,还有一个主要缺陷:该技术将从ComboBox中保存一个值,但是当你重新打开工作流程时它不会恢复它。

微软的Ron Jacobs has another answer为自定义活动设计师。我最终将这两者结合起来以获得有效的解决方案。

自定义设计器

ModelToObjectValueConverter是一个非常有用的资源,允许我跳过创建自己的IValueConverter。在ObjectDataProvider中,您看到我通过调用静态方法People.GetPeople()来加载字符串列表。 ComboBox作为项源绑定到该提供程序,但将所选值绑定到自定义Activity上的Person属性(下面)

<sap:ActivityDesigner x:Class="ActivityLibrary1.ComboBoxActivityDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    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"
    xmlns:c="clr-namespace:ActivityLibrary1">

    <sap:ActivityDesigner.Resources>
        <ResourceDictionary>
            <sapc:ModelToObjectValueConverter x:Key="ModelToObjectValueConverter" />
            <ObjectDataProvider x:Key="people" ObjectType="{x:Type c:People}" MethodName="GetPeople"/>
        </ResourceDictionary>
    </sap:ActivityDesigner.Resources>

    <Grid>
        <Label Content="Person" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <ComboBox HorizontalAlignment="Left" 
                  Margin="66,0,0,0" 
                  VerticalAlignment="Top" 
                  Width="120"
                  SelectedValue="{Binding Path=ModelItem.Person, Mode=TwoWay, Converter={StaticResource ModelToObjectValueConverter} }"
                  ItemsSource="{Binding Source={StaticResource people}}">
        </ComboBox>
    </Grid>
</sap:ActivityDesigner>

自定义代码活动

请注意,这使用属性而不是InArgument,这使得ComboBox的绑定更容易。

[Designer(typeof(ComboBoxActivityDesigner))]
public class CodeActivity1 : CodeActivity 
{      
    public string Person { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        // Just to demonstrate that it worked
        MessageBox.Show(Person);    
    }
}

<强>工作流

现在可以将自定义活动CodeActivity1拖到工作流程上。进行选择时,所选值将显示在属性窗格中。保存工作流程。关闭并重新打开。之前选择的值将根据需要保留。

screenshot of custom activity designer in action

答案 2 :(得分:2)

解决它的一种方法是定义自己的ComboBoxEditor,它派生自UITypeEditor。 在活动类中公开要绑定此组合框的集合,并使用以下属性修饰Activity类中的可绑定属性:

[EditorAttribute(typeof(CustomListBoxEditor), typeof(System.Drawing.Design.UITypeEditor))]

同样在自定义的comboboxEditor中,你必须修改你的 EditValue(ITypeDescriptorContext context,IServiceProvider provider,object value)方法获取集合并将其绑定到组合框。