locked
Collapse and expand an activity deletes the activity's ExpressionBlocks. RRS feed

  • Question

  • I have a custom activity with dynamic ExpressionBlocks drawn inside a grid.

    The activity designer code reads a certain property from the activity and according to some logics it fills the grid with a set of TextBlocks and ExpressionBlocks.

    It turn out that the grid can be quite large so I used Data Templates to collapse and expand the activity.

    In the activity's xsml all there is in the "Expanded" DataTamplate is an empty grid because I fill it dynamically.  

    I found out that when the activity is expanded all I get is the empty grid and I have to draw all the ExpressionBlocks again.

    The problem is that if the user filled the ExpressionBlocks with some data when I will redraw them the data will disappear.

    What can I do to make the designer save my work when collapsing and expanding a dynamically drawn activity?

    Thanks

    Manu

    Wednesday, June 2, 2010 7:54 PM

All replies

  • Hi manu,
    How are you recreating the ExpressionBlocks? Is the problem that you didn't recreate the data bindings? Or is the problem that the data entered earlier hasn't been committed to ModelTree/XAML?
    Tim

    Wednesday, June 2, 2010 11:15 PM
  • Hi, Manu

    Here is a sample implemented collapse and expand in an activity.
    http://xhinker.com/2010/03/16/WF4CreateACustomActivity.aspx
    It could be helpful to you

    Regards
    This posting is provided "AS IS" with no warranties, and confers no rights. Microsoft Online Community Support
    Friday, June 4, 2010 1:51 AM
  • Hi Tim

    Thanks for the quick response.

    Well I do use a Binding object in code and create a binding between the expression block (Expression property) and the relevant argument.

    I found out a very strange behavior of the designer.

    If I drag the activity, create the custom expression blocks dynamically (by filling one of the activity's properties) and fill the new expression blocks with VB expression they will disappear when collapsing and expanding the activity.

    If I build the new workflow after creating the custom expression blocks (before filling the expressions), the expression written to the new expression blocks will survive collapsing the activity.

    I cannot explain that.

    Tuesday, June 8, 2010 8:24 PM
  • Thanks but this sample is not relevant as it deals with static designer defined in xaml.

    My activity creates the designer in code based on one of the activity's properties.

    Manu

    Tuesday, June 8, 2010 8:26 PM
  • I'm afraid I still don't fully understand what you're doing, are you able to post any code?
    Tim

    Thursday, June 10, 2010 12:09 AM
  • Hi Tim

    Here is the code:

    As you can see the expression textbox are created in code and are binded to the activity's arguments
    (which are created in the CacheMetadata method).

    The problem is that the expression written to the expression textbox disappears when the activity is collapsed.
    Only after a few builds this phenomenon stops and the expression survives collapse and expand.

    public void DrawExpressionBoxOnCanvas(Grid activityGrid, string argumentName,Type argumentType, string direction, ModelItem ownerActivity)
      {
       //Create a new row in the activity grid
       int rowIndex = activityGrid.RowDefinitions.Count;
       var newRow = new RowDefinition();
       activityGrid.RowDefinitions.Insert(rowIndex, newRow);
    
       //Create a text block on the grid with the argument name
       var txtBlock = new TextBlock();
       txtBlock.Uid = "txtBlock" + argumentName;
       txtBlock.Text = argumentName;
       txtBlock.Margin = new Thickness() { Bottom = 5, Top = 5, Left = 5, Right = 5 };
       Grid.SetColumn(txtBlock, 0);
       Grid.SetRow(txtBlock, rowIndex);
       activityGrid.Children.Add(txtBlock);
    
       //Create a new ExpressionTextBox on the activity grid
       var expressionTbx = new ExpressionTextBox();
       expressionTbx.Uid = "ExpressionBox" + argumentName;
       expressionTbx.HintText = String.Format("Enter {0}", argumentName);
       expressionTbx.ExpressionType = argumentType;
       expressionTbx.Margin = new Thickness() { Bottom = 5, Top = 5, Left = 5, Right = 5 };
       expressionTbx.Width = 110;
       expressionTbx.OwnerActivity = ownerActivity;
    
       // Create binding between the expression block and the activity's arguments
       var bind = new Binding();
       bind.Mode = BindingMode.TwoWay;
       bind.Converter = new ArgumentToExpressionConverter();
       bind.ConverterParameter = direction;
       bind.Path = new PropertyPath(String.Format("ModelItem.Arguments[{0}]", argumentName));
          
       //Out arguments require L-Value expression 
       if (direction == "out")
        expressionTbx.UseLocationExpression = true;
    
       //Set the binding and Add the expression block to the grid 
       expressionTbx.SetBinding(ExpressionTextBox.ExpressionProperty, bind);
       Grid.SetRow(expressionTbx, rowIndex);
       Grid.SetColumn(expressionTbx, 1);
       activityGrid.Children.Add(expressionTbx);
      }

    Thanks

    Manu

     

    • Edited by manukahn Monday, June 14, 2010 8:04 PM spaelling
    Monday, June 14, 2010 8:03 PM
  • Oh this is for a dynamic list of arguments?

    I can't see anything that looks like a potential cause of data loss in the posted code.

    Just in case, but maybe this is a problem?

    As you can see the expression textbox are created in code and are binded to the activity's arguments
    (which are created in the CacheMetadata method).

    CacheMetadata will get called many times during design time, for the purpose of evaluating expressions. If you happen to recreate the arguments and threw away the old ones, that could be a problem. (Short term, your ETB may still be bound to the unlinked argument).

     Tim

    Monday, June 14, 2010 9:27 PM
  • Thanks Tim

    I did not show you my CacheMetadata code. I do not create arguments twice. I track changes.

    Arguments are created (once) in CacheMetadata and  the grid with its expression textboxes are created in the designer code.

    It looks like a "commit" problem. To commit the new arguments the WF developer has to build the new WF with the activity after the new arguments were created. Only then expression written to the expression textbox will survive collapse.

    Thanks anyway

    Manu

     

     

     

    Only the expression textbox are recreated

    Tuesday, June 15, 2010 7:15 PM
  • To try to better understand the problem problem, could you please try a couple things and let us know the result?

    (Each scenario starts with a blank ETB)

    1 - if you edit the expression, save the workflow with ctrl+S or whatever, and without collapsing the activity load the XAML file in notepad or whatever, does the expression appear correctly in the XAML file?

    2 - if instead you edit the expression, and immediately click collapse without having lost focus from ETB, and then after collapse save, does the expression appear correctly in the XAML file?

    3 - if instead you edit the expression, lose focus from ETB by clicking on the activity's display name, then finally save, again does the expression appear correctly in the XAML file?

    The questions should help test whether

    - the binding is working OK, as long as collapse/expand is not involved
    - the collapse action destroying/hiding ETB prevents ETB commit occuring
    - by comparison with result of 1 or 2, maybe something really weird can be detected.

    Also, you wondered why build could make a difference. The main reason I can think of is that when you build, then the designer reloads, the designer object is recreated, and at that point of creation it will possibly point to a differently configured modelitem than the unconfigured one it would be associated to when you drag/drop - but other reasons are possible... attaching a new instance of VS to act as a debugger while you edit may help.

    Tim

    Friday, June 18, 2010 4:19 AM