locked
Simple properties in Activity are lost when compiling or opening RRS feed

  • Question

  • I've got a custom Native Activity which looks something like this:

     

    public class MyActivity : NativeActivity
    {
     public Foo MySimpleProperty {get;set;}
     // blah blah
    

     

    and I've got a custom designer for it.  It has a list of options (Foo-s to choose from) that it binds against an ItemsControl.  The SelectedValue is bound to this simple property:

     

    <ListBox
     SelectedValue="{Binding ModelItem.TemplateType}"
     ItemsSource="{Binding AvailableFoos, ElementName=root}">
     <!-- element 'root' is the root of the designer -->
    

     

    It works perfectly.  If I save the workflow and check the xaml, I can see it was saved properly:

     

    <sci:MyActivity 
     MySimpleProperty="local:TheFooIPickedIsHere" />
    

     

    BUT... when I open the workflow or when the workflow is open and I compile the solution I lose the selected value of MySimpleProperty.  

    How can I prevent this from happening?

     

    Thursday, May 13, 2010 6:36 PM

Answers

  • Okay, I figured out what was going on (even though I wasn't getting any helpful error information in the Output window while debugging).  

    There was a difference between the type of the public property of the Activity (System.Type) and the type that was used as the DataContext of the ListBox (TemplateType, a model in my solution).  

    I needed to create an IValueConverter that Convert()ed a ModelItem to a TemplateType (from the Activity represented by the ModelItem to the design surface) and that would ConvertBack() from a TemplateType to a System.Type (from the design surface back to the property of my Activity).

    Doing this fixed the issue completely.  The impedance was the three way dance between my Activity, the ModelItem representation of the activity, and the design surface's use of TemplateType.

    Friday, May 14, 2010 4:20 PM

All replies

  • Hi Will,

    Quick answer: You need to set SelectedValuePath for your ListBox control.

    I did a little playing around with my own wpf app, and I think it's actually the listbox control that's causing your problem.  My listbox control looked something like this:

                <ListBox SelectedValue="{Binding Path=ModelItem.Text4, Mode=TwoWay}">
                    <ListBoxItem>hello</ListBoxItem>
                    <ListBoxItem>world</ListBoxItem>
                </ListBox>

    And I encountered the exact same behavior that you described.  However, I noticed that I was getting strange things like "System.Windows.Controls.ListBoxItem: hello" as my value, and setting SelectedValue directly was not working.  As it turns out, we actually want SelectedValue to set ListBoxItem.Content rather than the ListBoxItem itself.  Fortunately this is pretty easy to do by setting the SelectedValuePath property:

                <ListBox SelectedValue="{Binding Path=ModelItem.Text4, Mode=TwoWay}" SelectedValuePath="Content">
                    <ListBoxItem>hello</ListBoxItem>
                    <ListBoxItem>world</ListBoxItem>
                </ListBox>

    After doing this, everything worked the way I was expecting (the designer shows the selected items on load and the silly type information is not set in the property anymore)

     

    Relevent MSDN link: http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selectedvaluepath.aspx

    Hope this helps,

    Eric

     

    Thursday, May 13, 2010 9:41 PM
  • Unfortunately, no, that doesn't work.  SelectedValuePath is just the path within the object which is the DataContext of the item.  You don't have to set SelectedValuePath if you wish to bind against the DataContext directly; you only need it if the correct selected value should be a property of the DataContext instance.  Thanks for trying, tho.

     

    *note* I'm not getting any binding errors; everything works as expected.  I'm losing my bindings when opening and compiling (which results in the designer resetting).  Its some sort of impedance between the UI of the designer, the ModelItem representation of the Activity, and the Activity itself. 

    Friday, May 14, 2010 12:53 PM
  • Okay, I figured out what was going on (even though I wasn't getting any helpful error information in the Output window while debugging).  

    There was a difference between the type of the public property of the Activity (System.Type) and the type that was used as the DataContext of the ListBox (TemplateType, a model in my solution).  

    I needed to create an IValueConverter that Convert()ed a ModelItem to a TemplateType (from the Activity represented by the ModelItem to the design surface) and that would ConvertBack() from a TemplateType to a System.Type (from the design surface back to the property of my Activity).

    Doing this fixed the issue completely.  The impedance was the three way dance between my Activity, the ModelItem representation of the activity, and the design surface's use of TemplateType.

    Friday, May 14, 2010 4:20 PM