我有一个自定义活动,其中一个in参数是一个字符串。然而,我不希望设计者输入任意字符串,而是希望向设计者呈现带有选项列表的Combobox,这些选项是动态的,并且从数据库加载到List<>中。采集。
我的问题是我不知道如何将设计器中的Combobox绑定到此列表,并将选择设置为活动的in参数。在视觉上我让活动设计师工作,这只是一步。
答案 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
拖到工作流程上。进行选择时,所选值将显示在属性窗格中。保存工作流程。关闭并重新打开。之前选择的值将根据需要保留。
答案 2 :(得分:2)
解决它的一种方法是定义自己的ComboBoxEditor,它派生自UITypeEditor。 在活动类中公开要绑定此组合框的集合,并使用以下属性修饰Activity类中的可绑定属性:
[EditorAttribute(typeof(CustomListBoxEditor), typeof(System.Drawing.Design.UITypeEditor))]
同样在自定义的comboboxEditor中,你必须修改你的 EditValue(ITypeDescriptorContext context,IServiceProvider provider,object value)方法获取集合并将其绑定到组合框。