MissingMethodException from TriggerAction

MissingMethodException from TriggerAction

Old forum URL: forums.lhotka.net/forums/t/11057.aspx


TSF posted on Friday, January 13, 2012

I'm trying to use a ChildWindow for the first time in SL4, and I'm getting a MissingMethodException raised from a trigger action within the child window.  I'm not sure if this is right or wrong, but the only way I could figure out how to get my child window's data context to use the parent window's data context was to do this in the parent view's code-behind:

childWindow.DataContext = myViewModel;
childWindow.Show();

In the child window's trigger action, the MethodName is equal to a public method in the parent's view model.  But when I click on the button in the child window, the trigger action throws the MissingMethodException:  at Csla.Xaml.TriggerAction.CallMethod...

Can a trigger action be used in a child window?  If so, what am I doing wrong?  Thanks.

RockfordLhotka replied on Friday, January 13, 2012

In the current code TriggerAction will write binding errors to the debug window in Visual Studio, just like other controls write their binding errors. This should include the method name and data context value - and that information might be quite helpful in troubleshooting your issue.

TSF replied on Friday, January 13, 2012

Thank you.  That was helpful to get a little further.  What I found is the following, which isn't what I expected.  It looks like it is trying to find the method by looking in the underlying model (my business object) rather than in my VM:

Csla.Xaml.TriggerAction Error: CallMethod path error: 'AddGadget' method not found on 'Test.Business.GadgetInfo', DataContext 'Test.Business.GadgetInfo'

The only thing I can think of is this:  this particular trigger action is in a DataTemplate used by an ItemsControl.  And the ItemsControl's ItemSource is set to {Binding MyList}.  To clarify, in the data template, I have a button and then this trigger action:

<csla:TriggerAction MethodName="AddGadget"
          MethodParameter="{Binding GadgetName}"
          TargetControl="{Binding ElementName=btnAddGadget}"
          TriggerEvent="Click"
          DataContext="{Binding}"/>

The {Binding} in the trigger action's DataContext must be referring to the GadgetInfo object instead of the view model.  But in reality I sort of want both:  I want the MethodParameter to refer to the GadgetInfo object, but I also want to have the MethodName refer to a method on the VM and not the GadgetInfo object.  Is this just a case of bad design on my part?  Is there a way to refer to the binding's parent so that the MethodName refers to a method on the VM instead of the Model?  Thanks.

 

 

TSF replied on Friday, January 13, 2012

In answer to my previous question, this is what I came up with.  Feels a little messy, though:

<DataTemplate x:Key="gadgetDataTemplate">

...
<Button Name="btnAddGadget" Tag="{Binding GadgetName}" Content="Add Gadget" />
      
<csla:TriggerAction MethodName="AddGadget"
          MethodParameter="{Binding Tag, ElementName=btnAddGadget}"
          TargetControl="{Binding ElementName=btnAddGadget}"
          TriggerEvent="Click"
          DataContext="{Binding DataContext, ElementName=ic}"/>
...

</DataTemplate>

<ItemsControl Name="ic"
    DataContext="{Binding}"
    ItemsSource="{Binding GadgetList}"
    ItemTemplate="{StaticResource gadgetDataTemplate}"  />

I changed the TA's data context to that of the ItemsControl so that it would pick up the VM instead of the GadgetInfo BO.  Because I still needed to get the MethodParameter equal to the current item's name (GadgetName), I bound that to the button's Tag property because the button's data context was the list of GadgetInfo objects.  Finally, I referenced that tag property in the TA's MethodParameter.  Round about way of doing it but it worked.

Copyright (c) Marimer LLC