views:

433

answers:

2

I have a custom class called "Parameter" and a custom activity with generic collection property called "Parameters", and I want to set bindings for one of Parameters in the generic list of Parameters Property,I've tried with activitybind, but it is not working, is there any way to do it with workflow foundation? please see codes below:

public class Parameter:DependencyObject //A Class
{
public string Name
{
    get { return (string)GetValue(NameProperty); }
    set { SetValue(NameProperty, value); }
}

// Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty NameProperty =
    DependencyProperty.Register("Name", typeof(string), typeof(Parameter));

public string Value
{
    get { return (string)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}

// Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
    DependencyProperty.Register("Value", typeof(string), typeof(Parameter));
}

//A Custom Activity with generic property

    public partial class Activity1 : System.Workflow.ComponentModel.Activity
{
 public Activity1()
 {
  InitializeComponent();
 }

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
    return base.Execute(executionContext);
}

public List<Parameter> Parameters
{
    get { return (List<Parameter>)GetValue(ParametersProperty); }
    set { SetValue(ParametersProperty, value); }
}

// Using a DependencyProperty as the backing store for Parameters.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ParametersProperty =
    DependencyProperty.Register("Parameters", typeof(List<Parameter>), typeof(Activity1));

//Designer Code

   #region Designer generated code

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor.
    /// </summary>
    [System.Diagnostics.DebuggerNonUserCode]
    private void InitializeComponent()
    {
        this.CanModifyActivities = true;
        this.activity12 = new ActivityLibrary1.Activity1();
        this.activity11 = new ActivityLibrary1.Activity1();

        List<Parameter> paras1 = new List<Parameter>();
        paras1.Add(new Parameter() { Name = "a", Value = "a" });
        paras1.Add(new Parameter() { Name = "b", Value = "b" });

        List<Parameter> paras2 = new List<Parameter>();
        paras2.Add(new Parameter() { Name = "c", Value = "c" });
        paras2.Add(new Parameter() { Name = "d", Value = "d" });
        // 
        // activity12
        // 
        this.activity12.Name = "activity12";
        this.activity12.Parameters = paras1;
        // 
        // activity11
        // 
        this.activity11.Name = "activity11";
        this.activity11.Parameters = paras2;


        ActivityBind bind = new ActivityBind();
        bind.Name = activity11.Name;
        bind.Path = "Parameters[0].Value";

        activity12.Parameters[0].SetBinding(Parameter.ValueProperty, bind);
        // 
        // Workflow1
        // 
        this.Activities.Add(this.activity11);
        this.Activities.Add(this.activity12);
        this.Name = "Workflow1";
        this.CanModifyActivities = false;

    }

    #endregion

    private ActivityLibrary1.Activity1 activity12;
    private ActivityLibrary1.Activity1 activity11;
+1  A: 

I just ran into this same issue and I solved it by simply eliminating the need for the collection.

You could do the same pretty easily:

public class Parameters {
  private Dictionary<string, string> _parameters;

  public void Add(string name, string value) {
    _parameters.Add(name, value);
  }
}

You can then bind that to your dependency property instead of the list.

Chris Stavropoulos
+2  A: 

I've been doing some additional work in this area as my previous answer, although technically usable isn't really ideal. So I've come up with a better solution.

Basically, when binding properties, the built in designer 'guesses' as to which control to load up when you click the ellipsis in the property box. When you point it to a list, it loads up some fancy editor that lets you manually add list items, which is basically useless for any sort of dynamic data scenarios.

I did some digging and tripped across this post: http://blogs.microsoft.co.il/blogs/bursteg/archive/2006/10/29/DynamicWorkflowBindingParameters.aspx

It wasn't exactly what I needed, but it did clue me in to the Editor attribute.

The 'what do I need to know' part of this answer is here, simply add this attribute to your property declaration (the actual property, not the DependencyProperty backing field):

[Editor(typeof(BindUITypeEditor), typeof(UITypeEditor))]

That will force the GUI to load up the dependency property binding interface.

This isn't really a shortcoming of the workflow framework itself, but it was kind of annoying to have to dig into this so deeply to figure out the solution. It just seems everywhere you turn with windows workflow, the questions are there but not the answers.

Anyways, I hope this helps you or someone else if you run into this issue.

Chris Stavropoulos