代码之家  ›  专栏  ›  技术社区  ›  Chris Taylor

将数据绑定到自定义活动设计器中的组合框

  •  9
  • Chris Taylor  · 技术社区  · 14 年前

    我有一个自定义活动,其中一个是字符串。但是,我不希望让设计器输入任意字符串,而是希望向设计器显示一个包含选项列表的组合框,这些选项是动态的,并从数据库加载到列表集合中。

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

    3 回复  |  直到 10 年前
        1
  •  7
  •   Luis    11 年前

    通常,我会用 property 而不是 InArgument . 这简化了场景:

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

    (这里validOptions是ActivityDesigner类的一些集合属性。myStringProperty是基础活动的某些公共get/set/property,例如:

    public string MyStringProperty { get; set; }
    

    )

    如果你再加上 论据 组合框中的字符串值不能直接分配给 ModelItem 期望 InArgument<string> . 使用自定义 IValueConverter 在你的束缚中。

        2
  •  4
  •   sfuqua    10 年前

    以前的答案很有用,但对我来说还不够。最终,我在微软的.NET 4.5开发人员指南中找到了一篇2012年的优秀文章: binding a custom activity property to a designer control.>除了自定义转换器类中的一个小错误和一个主要缺陷外,这篇文章几乎是完整答案:该技术将从组合框中保存一个值,但当您重新打开工作流时,它将不会还原该值。

    Microsoft的Ron Jacobs has another answer for custom activity designer s.最后,我将两者结合起来,得到了一个有效的解决方案。

    自定义设计器

    modelToObjectValueConverter 是一个非常有用的资源,允许我跳过创建自己的 ivalueConverter 。在 ObjectDataProvider You see me loading a list of strings by calling a static method, People.getPeople() 。组合框作为项目源绑定到该提供程序,但将所选值绑定到自定义活动(下面)的Person属性

    <sap:ActivityDesigner x:class=“ActivityLibrary1.ComboBoxActivityDesigner”
    xmlns=“http://schemas.microsoft.com/winfx/2006/xaml/presentation”(http://schemas.microsoft.com/winfx/2006/xaml/presentation)
    xmlns:x=“http://schemas.microsoft.com/winfx/2006/xaml”
    xmlns:sap=“clr命名空间:system.activities.presentation;assembly=system.activities.presentation”
    xmlns:sapc=“clr命名空间:system.activities.presentation.converters;assembly=system.activities.presentation”
    xmlns:sapv=“clr命名空间:system.activities.presentation.view;assembly=system.activities.presentation”
    xmlns:c=“clr-namespace:activitylibrary1”>
    
    <sap:activitydesigner.resources>
    <资源字典>
    <sapc:modelToObjectValueConverter x:key=“modelToObjectValueConverter”/>
    <objectDataProvider x:key=“people”objectType=“x:type c:people”methodname=“getPeople”/>gt;
    </resourcedictionary>
    </sap:activitydesigner.resources>
    
    格栅& GT;
    <label content=“person”horizontallight=“left”verticalalightment=“top”/>
    <ComboBox Horizontalalignment=“左”
    margin=“66,0,0,0”页
    VerticalAlignment=“顶部”
    宽度=“120”
    selectedValue=“绑定路径=modelItem.person,模式=twoway,converter=staticResource modelToObjectValueConverter”
    itemssource=“绑定源=静态资源人员”>
    </ComboBox>
    和/格栅& GT;
    </SAP:ActivityDesigner>
    < /代码> 
    
    

    自定义代码活动

    请注意,这使用的是一个属性而不是一个不一致的属性,这使得绑定组合框更加容易。

    [designer(typeof(combobxactivitydesigner))]
    公共类codeActivity1:codeActivity
    {
    公共字符串person get;set;
    
    受保护的重写void execute(codeActivityContext上下文)
    {
    //只是为了证明它有效
    messagebox.show(人);
    }
    }
    < /代码> 
    
    

    工作流

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

    从2012年起,在Microsoft的.NET 4.5开发人员指南中:Binding a custom activity property to a designer control. 除了自定义转换器类中的一个小错误和一个主要缺陷外,这篇文章几乎是完整的答案:该技术将从组合框中保存一个值,但当您重新打开工作流时,它将不会恢复该值。

    微软的Ron Jacobshas another answer用于自定义活动设计器。最后我把两者结合起来,得到了一个可行的解决方案。

    定制设计器

    这个ModelToObjectValueConverter是一个非常有用的资源,允许我跳过创建自己的IValueConverter. 在ObjectDataProvider您看到我通过调用静态方法加载字符串列表,People.GetPeople(). 组合框作为项目源绑定到该提供程序,但将所选值绑定到自定义活动的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>
    

    自定义代码活动

    请注意,这使用的是一个属性而不是一个不一致的属性,这使得绑定组合框更加容易。

    [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

        3
  •  2
  •   Cody Gray    13 年前

    解决这个问题的一种方法是定义自己的ComboBoxeditor,它是从UITypeEditor派生的。 公开要在Activity类中绑定此组合框的集合,并用以下属性装饰Activity类中的可绑定属性:

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

    此外,在自定义ComboBoxeditor中,必须修改 EditValue(ITypedDescriptorContext Context、IServiceProvider Provider Provider、Object Value)方法获取集合并将其绑定到组合框。