ActionCommand never fires

Feb 23, 2011 at 7:13 AM

Hi,

I cannot seem to get the ActionCommand to execute. I know the nRoute mapping is correct because the constructor works and should I set the data there it is visible via UI.

Here is the XAML

 

<in:Interaction.Triggers>
       <in:EventTrigger EventName="MouseLeftButtonDown">
                    <n:ExecuteCommandAction Command="{Binding Mode=OneTime, Path=RefreshCommand}" />
                    <ei:GoToStateAction StateName="Click"/>                   
       </in:EventTrigger>

Here is the ViewModel

[MapViewModel(typeof(MainPage))]
    public class MainPageViewModel : ViewModelBase
    {
        private NavigationList _navigationData;
        public NavigationList NavigationData
        {
            get
            {
                return _navigationData;
            }
            set
            {
                if (_navigationData != value)
                {
                    _navigationData = value;
                    NotifyPropertyChanged(() => NavigationData);
                }
            }
        }  
        private ICommand _refreshCommand;
        public ICommand RefreshCommand
        {
            get { return _refreshCommand; }            
        }
        public MainPageViewModel()
        {
            _refreshCommand = new ActionCommand(() =>
                {
                    NavigationList nl = NavigationModel.GetNavigationList();
                    NavigationData = nl;
                }, true);
        }
    }
Any helf appreciated
Coordinator
Feb 23, 2011 at 8:19 AM

Hi, I'm going to go out on a limb and say the problem most likely is the EventTrigger's event selection - on a button "MouseLeftButtonDown" gets subverted. Other than that, the refresh command should work I did a small repo using your code, see: http://cid-587cbdf035b4a11d.office.live.com/self.aspx/.Public/CommandTestApp.zip 

Cheers,
Rishi 

Feb 24, 2011 at 7:44 AM

Your thinking got me thinking :) It was actually the parent control having a datacontext set which meant the RefreshCommand was looking in the wrong place.

Just on another note do you suggest using your NavigationFramework or the one that comes with Silverlight 4 (maybe they are one and the same)

I easily managed to get the standard Navigation Framework to work but I can't seem to get your NavigationAction to behave.

No error just nothing changes.

Do you have a easy example of how to set it up?

Thanks

Jeremy

Coordinator
Feb 24, 2011 at 9:47 AM

Well, I'm biased but you get a number of advtanges using nRoute's navigation framework, for example:

  • State Management, so as you navigate back and forward you can save/restore state
  • Various Navigation Containers, this allows you to have different kinds of use semantics such as stateful navigation 
  • Asynchronous Navigation, so that you can interject navigation process and confirm/stop the process
  • MVVM friendly, for example you get Visual-free hooks into the navigation process
  • SiteMaps, allow you to decompose your application into loosely-coupled modules at design-time, and recompose it at runtime
  • Navigation Parameters allow you to pass around data whilst navigation, this simplifies a lot of the inter-communication issues 

Also, incase you choose not to use nRoute's navigation framework, consider using nRoute's Toolkit - its got a lot of helpful functionality sans the navigation infrastructure.

Secondly, to get nRotue's navigation working at minimum you need to:

Also, I'd recommend you look into the samples I've listed on codeplex, along with read-ups from my blog, for example: 

http://www.orktane.com/Blog/post/2010/06/30/Creating-a-Netflix-App-using-nRoute-A-Step-by-Step-Guide.aspx
http://www.orktane.com/Blog/post/2009/05/22/Step-into-nRoute-e2809cOfficec2ae-2010e2809d-Demo-App.aspx

Hope this helps,
Rishi 

Feb 24, 2011 at 3:11 PM

The State Management sounds like a very useful feature.

When I call 

 NavigationService.Navigate(new NavigationRequest("/Views/Dynamic", NavigateMode.Forward));

I get a Stack Empty error

 

{System.InvalidOperationException: Stack empty.   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)   at System.Collections.Generic.Stack`1.Pop()   at nRoute.Controls.StatefulBrowsingContainer.OnProcessResponse(NavigationResponse response)   at nRoute.Controls.NavigationContentControl.<>c__DisplayClass1.<ShowFailedNavigationState>b__0(NavigationResponse r)   at nRoute.Navigation.NavigationService.<>c__DisplayClassc.<Resolve>b__b(IUrlResponse r)   at nRoute.Components.Routing.RoutingService.OnResolveResponse(IRoutingContext context, Boolean throwException, Action`1 responseCallback)   at nRoute.Components.Routing.RoutingService.<>c__DisplayClass1.<Resolve>b__0(IRoutingContext c, ResponseStatus s)   at nRoute.Components.Routing.RoutingService.OnResolveRequest(IUrlRequest request, Boolean throwException, Action`2 requestCallback)   at nRoute.Components.Routing.RoutingService.Resolve(IUrlRequest request, Action`1 responseCallback)   at nRoute.Navigation.NavigationService.Resolve(NavigationRequest navigationRequest, Action`1 responseCallback)   at nRoute.Controls.NavigationContentControl.ShowFailedNavigationState(NavigationRequest request, ResponseStatus status, Exception error)   at nRoute.Controls.NavigationContainer.OnNavigatingFailed(NavigationFailedEventArgs e)   at nRoute.Controls.NavigationContainer.OnProcessResponse(NavigationResponse response)   at nRoute.Controls.StatefulBrowsingContainer.OnProcessResponse(NavigationResponse response)   at nRoute.Controls.NavigationContentControl.nRoute.Navigation.INavigationHandler.ProcessResponse(NavigationResponse response)   at nRoute.Navigation.NavigationService.<>c__DisplayClass10.<Navigate>b__f(NavigationResponse r)   at nRoute.Navigation.NavigationService.<>c__DisplayClassc.<Resolve>b__b(IUrlResponse r)   at nRoute.Components.Routing.RoutingService.OnResolveResponse(IRoutingContext context, Boolean throwException, Action`1 responseCallback)   at nRoute.Components.Routing.RoutingService.<>c__DisplayClass1.<Resolve>b__0(IRoutingContext c, ResponseStatus s)   at nRoute.Components.Routing.RoutingService.OnResolveRequest(IUrlRequest request, Boolean throwException, Action`2 requestCallback)   at nRoute.Components.Routing.RoutingService.Resolve(IUrlRequest request, Action`1 responseCallback)   at nRoute.Navigation.NavigationService.Resolve(NavigationRequest navigationRequest, Action`1 responseCallback)   at nRoute.Navigation.NavigationService.<>c__DisplayClass10.<Navigate>b__e(Boolean b)   at nRoute.Controls.NavigationContentControl.OnProcessRequest(NavigationRequest request, Action`1 requestCallback)   at nRoute.Controls.NavigationContainer.OnProcessRequest(NavigationRequest request, Action`1 requestCallback)   at nRoute.Controls.NavigationContentControl.nRoute.Navigation.INavigationHandler.ProcessRequest(NavigationRequest request, Action`1 requestCallback)   at nRoute.Navigation.NavigationService.Navigate(NavigationRequest navigationRequest, INavigationHandler navigationHandler, Action`1 statusCallback)   at nRoute.Navigation.NavigationService.Navigate(NavigationRequest navigationRequest, Action`1 statusCallback)   at nRoute.Navigation.NavigationService.Navigate(NavigationRequest navigationRequest)   at ChildcareCentreHandheld.NavigationGridControl.ListBox_SelectionChanged(Object sender, SelectionChangedEventArgs e)   at System.Windows.Controls.Primitives.Selector.OnSelectionChanged(SelectionChangedEventArgs e)   at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List`1 unselectedItems, List`1 selectedItems)   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()   at System.Windows.Controls.Primitives.Selector.OnItemsChanged(NotifyCollectionChangedEventArgs e)   at System.Windows.Controls.ListBox.OnItemsChanged(NotifyCollectionChangedEventArgs e)   at System.Windows.Controls.ItemsControl.OnItemCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)   at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)   at System.Windows.Controls.ItemCollection.UpdateItemsSourceList(IEnumerable newItemsSource)   at System.Windows.Controls.ItemsControl.ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)   at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object oldValue, Object newValue)   at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)   at System.Windows.DependencyObject.RefreshExpression(DependencyProperty dp)   at System.Windows.Data.BindingExpression.SendDataToTarget()   at System.Windows.Data.BindingExpression.SourcePropertyChanged(PropertyPathListener sender, PropertyPathChangedEventArgs args)   at System.Windows.PropertyPathListener.RaisePropertyPathStepChanged(PropertyPathStep source)   at System.Windows.PropertyAccessPathStep.RaisePropertyPathStepChanged(PropertyListener source)   at System.Windows.CLRPropertyListener.SourcePropertyChanged(Object sender, PropertyChangedEventArgs args)   at System.Windows.Data.WeakPropertyChangedListener.PropertyChangedCallback(Object sender, PropertyChangedEventArgs args)   at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e)   at nRoute.Components.PropertyChangedExtensions.Notify[T](PropertyChangedEventHandler handler, Expression`1 propertySelector)   at nRoute.ViewModels.ViewModelBase.NotifyPropertyChanged[T](Expression`1 propertySelector)   at ChildcareCentreHandheld.ViewModel.MainPageViewModel.set_NavigationData(NavigationList value)   at ChildcareCentreHandheld.NavigationGridControl.ListBox_SelectionChanged(Object sender, SelectionChangedEventArgs e)   at System.Windows.Controls.Primitives.Selector.OnSelectionChanged(SelectionChangedEventArgs e)   at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List`1 unselectedItems, List`1 selectedItems)   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()   at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(Int32 oldIndex, Int32 newIndex)   at System.Windows.Controls.ListBox.MakeSingleSelection(Int32 index)   at System.Windows.Controls.ListBox.HandleItemSelection(ListBoxItem item, Boolean isMouseSelection)   at System.Windows.Controls.ListBox.OnListBoxItemClicked(ListBoxItem item)   at System.Windows.Controls.ListBoxItem.OnMouseLeftButtonDown(MouseButtonEventArgs e)   at System.Windows.Controls.Control.OnMouseLeftButtonDown(Control ctrl, EventArgs e)   at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)}

Coordinator
Feb 24, 2011 at 10:03 PM

Well, you are trying to go forward (like in a browser) however in this case there is nothing to go forward to, so basically you need to check (use CanNavigateForward property) before you attempt to navigate. All the same, if you intention was to just navigate to a new page, use the New value on NavigateMode.

Also, for normal use I'll recommend the use of built-in trigger actions - like NavigateAction or DirectionalNavigateAction.

Cheers,
Rishi 

Feb 25, 2011 at 12:50 AM

Ahh that makes sense now. A quick question.

When I use a trigger for NavigateAction I can see it navigate to the page however the URL in the browser does not change.

Many Thanks

Jeremy

Coordinator
Feb 25, 2011 at 11:33 AM

Sorry John that's not right - Jeremy to make the url change you need to specifically enable browser-shell to container integration and you do so by attaching the NavigationShellIntegration behavior onto the navigation container. From my blog post (http://www.orktane.com/Blog/post/2010/04/13/nRoute-Now-More-Wholesome.aspx):

Browser-Shell Integration

Browser-shell integration was earlier quite messy, now all you need to do is to drop the NavigationShellIntegrationBehaviour and you are done - clean and simple, and there are no options to fiddle around too.

NavigationShellBehaviour
This behavior makes use of the Silverlight's built-in Browser-History Manager, however it has the limitation of only being forward-only, which means you can't use it with navigation containers that allow directional navigation (like BrowsingNavigationContainer). For use with direction-aware containers I'll release an out-of-bound behavior, which will use of a different Browser-History Manager. Also, note this behavior is not available for WP7 or WPF, and when in Out Of Browser (OOB) mode it disarms itself.

Rishi