EventToCommand and SizeChanged

Feb 26, 2010 at 11:47 AM

Firstly, love the toolkit. Very intuitive. Good work!

I'm experiencing a small issue with EventToCommand in a sl3 app. I need to monitor the size of an element, so I've implemented a RelayCommand<SizeChangedEventArgs> in my VM to which I have bound the SizeChanged event using EventToCommand.

It seems to work fine, except for the fact that the first time the event fires (directly prior to the element's Loaded event) the RelayCommand is not called. Each subsequent SizeChanged event calls successfully, just not the initial event.

Is this expected behaviour, a bug or could it be something I've done wrong?

Thanks.

Coordinator
Feb 28, 2010 at 11:59 AM

Hi,

Honestly, I am not sure. Could it be that the first time SizeChanged is called, the RelayCommand is not "wired" yet?

If you send me a repro, I will take a look at the sequence of events.

Thanks,

Laurent

Mar 3, 2010 at 10:18 AM

Laurent,

Thanks for getting back to me. Have tried to make a repro project, but the same behaviour does not manifest. I can only conclude that the issue must be contained within my project, so I'll investigate further and update if I get to the bottom of the problem.

I had the same thought about the wiring, and it seems the most likely explanation, but I have confirmed that the ViewModel & RelayCommand are created prior to the element's creation so I'm not sure where the problem could be arising.

Regards,

Sep 16, 2010 at 10:09 PM

I am having the same issue.  I have a control which I need an accurate Height and Width for.  I have the Height and Width in the ViewModel bound to the control (the view) but the size never seems to get updated on the view model end.  I figured I could use the SizeChanged event so I set up my trigger like so:

    <i:Interaction.Triggers>
        <!-- Wire the MouseLeftButtonDown event to the corresponding command in the ViewModel -->
        <i:EventTrigger EventName="SizeChanged">
            <cmd:EventToCommand Command="{Binding SizeChangedCommand}" PassEventArgsToCommand="True"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

However, the command is never called.  I confirm that SizeChanged is firing by setting up a view-side event handler but it never seems to fire the command.

Sep 17, 2010 at 8:16 AM

Sorry to say I never really resolved it so cannot help you, though it has been some time since I revisited the issue, in my case I worked around it by simply using an event handler on the SizeChanged element event and changing the public W/H values on my static ViewModel instance from that code-behind handler.

A little dirty, but it works just as well as any other way. Good luck.

Sep 17, 2010 at 2:24 PM

Thanks.  My research revealed that we are not the only ones with the issue and not everyone is using the MVVM Light Framework.  Most seem to have the problem related with the event being fired on an object within an ItemsControl (which is my case).  It appears to be some bug in Silverlight itself.  I worked around it by creating a behavior that handles the SizeChanged event and calls the specified command on the viewmodel.  This is exactly what the RelayCommand and EventToCommand were supposed to be doing but aren't working.  My behavior works perfectly.

Coordinator
Sep 17, 2010 at 6:02 PM

Hey guys,

Just to clarfiy, i am monitoring this thread and I will definitely investigate. I might come back to you then to ask for some code if you allow. I am just too swamped in the morning to progress on MVVM Light, but this will clear up after the WP7 launch.

Thanks for helping each other ;)

Cheers,

Laurent

Sep 17, 2010 at 6:30 PM

Its ok Laurent.  I totally understand.  As I mentioned, I found a work around.

I suspect that there is some sort of timing issue involved here.  SInce it works fine with a behavior, it should work with a trigger but something must be happening under the hood.  My behavior is still calling a command on my ViewModel that is using RelayCommand.  All my behavior does it handle the SizeChanged event fired by the attached object and calls the corresponding command.

Good luck with the WP7 stuff and PDC (if you will be there).

Todd

Oct 14, 2010 at 10:51 AM
Edited Oct 14, 2010 at 1:00 PM

Hi,

I had the same problem with another event. I have debugged the MVVM Light source code and I found why my command was not called.
Laurent, the problem is on the Invoke method : you check if the AssociatedElement is well enabled. In some cases, we would like the command to be called even if the control is not enabled. I think it could be the same problem with SizeChanged event.

A new boolean property on the EventCommand class will be welcome -  public bool YouMustInvokeTheCommandEvenIfTheControlIsDisabled ;-)

Or you could replace the line :
if (AssociatedElementIsDisabled()) { return; } - I don't know if checking IsEnabled property value of the control is a good idea or not
by
if (AssociatedObject == null) { return; }
It's what I did for the moment, waiting a fix...

Cordially,
Stéphane.

Jul 21, 2011 at 5:34 AM
Edited Jul 21, 2011 at 5:41 AM

Ran into the same issue with SL5 Beta and a modified MVVM Toolkit 4. We worked around it for now by doing the following on the view's codebehind

   public MyView()
    {
      InitializeComponent();
      MyLayoutRoot.SizeChanged += new SizeChangedEventHandler(MyLayoutRoot_SizeChanged);
    }

    void MyLayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
    {
      IMyViewModel vm = (IMyViewModel)this.DataContext;
      vm.RootGridWidth = ((Grid)sender).ActualWidth;
    }

Would be reassuring to know that this would be addressed in the next release. Thank you very much,

Mohamad.

Aug 2, 2011 at 11:00 AM
Edited Aug 2, 2011 at 11:05 AM

For the moment (I use the MVVM Light V4 preview 2), I saw no change about this. I hope that Laurent will add a new property on the EventCommand to invoke the command even the control is disabled, but I don't think that will resolve the problem with the SizeChanged event.

Cordially,
Stéphane.