argumentsworkflow-foundationactivitydesigner

How to access activity Argument within ActivityDesigner?


I need to get my custom activity's InArgument value at ActivityDesigner.

MyActivity:

[Designer(typeof(ReadTextDesigner))]
public sealed class ReadText : CodeActivity
{
    public InArgument<string> ImageName { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
    }
}

My designer:

public partial class ReadTextDesigner
{
    public ReadTextDesigner()
    {
        InitializeComponent();
        //this.ModelItem is null here.. WHY is it null?
        //How do I get Activity's ImageName here?
    }
}

I also have a button as in the image below and when you click on it, I CAN SET my custom Activity's value like this:

enter image description here

private void BtnStart_OnClick(object sender, RoutedEventArgs e)
    {
        this.ModelItem?.Properties["ImageName"]?.SetValue(new InArgument<string>()
        {
            Expression = "some value"
        });
    }

XAML:

<sapv:ExpressionTextBox 
    Expression="{Binding Path=ModelItem.ImageName, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In }"
    ExpressionType="s:String"
    HintText="Enter a string"
    OwnerActivity="{Binding Path=ModelItem}"
    Width="110"
    Margin="0,5"
    Grid.Row="0"
    MaxLines="1"
    x:Name="TxtImagePath"/>

<Button Grid.Column="0" Grid.Row="1" Content="Get Image" HorizontalAlignment="Center" Click="BtnStart_OnClick" x:Name="BtnStart"/>

How do I GET Activity InArgument ReadTextDesigner constructor?


Solution

  • Its quite weird but I found a workaround. Although this is A solution, I'm hoping for a much better one;

    Since within the constructor, I cannot get the ModelItem, I created a new Thread apart from the Main Thread. This new Thread waits 2 milliseconds and then tries to get ModelItem and it succeeds somehow.

    Here is the new modified ReadTextDesigner code (Note: I only changed ReadTextDesigner code nothing else)

    public ReadTextDesigner()
    {
        InitializeComponent();
    
        new TaskFactory().StartNew(() => { this.Dispatcher.Invoke(() => SetImage(this)); });
    }
    
    private void SetImage(ReadTextDesigner designer)
    {
        Thread.Sleep(2);
        if (designer.ModelItem.GetCurrentValue() is ReadText readText)
        {
            var imageName = readText.ImageName?.Expression?.Convert<string>();
            if (!string.IsNullOrWhiteSpace(imageName))
            {
                //imageName has a value at this point!
            }
        }
    }
    

    ModelItem is not null anymore and carries the necessary value. Hope this will help someone or someone post a better solution.

    Cheers!