11

文字列である単一の引数を持つカスタムアクティビティがあります。ただし、デザイナーが任意の文字列を入力できるようにするのではなく、オプションのリストを含むコンボボックスをデザイナーに提示する必要があります。オプションは動的であり、データベースからList<>コレクションに読み込まれます。

私の問題は、デザイナーのコンボボックスをこのリストにバインドし、選択をアクティビティの引数に設定する方法がわからないことです。視覚的には、アクティビティデザイナーが働いています。これは、この1つのステップにすぎません。

4

3 に答える 3

8

通常、私はアクティビティをではpropertyなくで記述しInArgumentます。これにより、シナリオが簡略化されます。

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

(ここで、ValidOptionsはActivityDesignerクラスのCollectionプロパティです。MyStringPropertyは、次のような基になるアクティビティのpublic get /set/プロパティです。

public string MyStringProperty { get; set; }

)。

ミックスに追加する場合の問題は、コンボボックスの文字列値を期待InArgument値に直接割り当てることができないことです。これは、バインディングのカスタムを使用して修正できます。ModelItemInArgument<string>IValueConverter

于 2010-04-28T20:48:23.880 に答える
6

以前の回答は役に立ちましたが、私には十分ではありませんでした。最終的に、Microsoftの.Net 4.5開発者ガイド:カスタムアクティビティプロパティをデザイナーコントロールにバインドするという、2012年のすばらしい記事を見つけました。その記事はほぼ完全な答えでした-カスタムコンバータークラスの小さなバグと大きな欠陥を除いて:そのテクニックはComboBoxから値を保存しますが、ワークフローを再度開いたときに値を復元しません。

MicrosoftのRonJacobsは、カスタムアクティビティデザイナーのための別の答えを持っています。私は2つを組み合わせて、実用的なソリューションを得ることになりました。

カスタムデザイナー

これModelToObjectValueConverterは非常に役立つリソースであり、自分で作成することをスキップできましたIValueConverter。静的メソッドを呼び出して文字列のリストを読み込んでいるのObjectDataProviderがわかりますPeople.GetPeople()。ComboBoxは、アイテムソースとしてそのプロバイダーにバインドしますが、選択した値をカスタムアクティビティの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、、をワークフローにドラッグできます。選択すると、選択した値がプロパティペインに表示されます。ワークフローを保存します。閉じてから再度開きます。以前に選択した値は、必要に応じて保持されます。

動作中のカスタムアクティビティデザイナーのスクリーンショット

于 2014-03-26T00:24:33.827 に答える
2

これを解決する1つの方法は、UITypeEditorから派生した独自のComboBoxEditorを定義することです。このコンボボックスをアクティビティクラスにバインドするコレクションを公開し、アクティビティクラスのバインド可能なプロパティを次の属性で装飾します。

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

また、カスタムコンボボックスエディターでは、EditValue(ITypeDescriptorContextコンテキスト、IServiceProviderプロバイダー、オブジェクト値)メソッドを変更して、コレクションを取得し、コンボボックスにバインドする必要があります。

于 2011-04-11T08:16:50.037 に答える