This project is read-only.

How can i use NavigationHelper.FindFrame in a viewmodel?

May 9, 2013 at 6:14 PM
If i am within a viewmodel,
var frame = NavigationHelper.FindFrame(null, this);
will not work because "this" is not a System.Windows.FrameworkElement. Is there a way to find the current frame?

I am trying to navigate from an event.
May 13, 2013 at 10:08 PM
Edited May 13, 2013 at 10:08 PM
MVVM purists wouldn't allow you to access UI elements in a view model. What are you trying to achieve?
May 15, 2013 at 9:52 PM
Edited May 15, 2013 at 9:52 PM
I ran into this same issue, it's something that has been mentioned in a number of other threads on this discussion board. Basically, in MVVM you can't get a handle to the FrameworkElement (your UserControl) in your ViewModel to allow you to initiate navigation from the ViewModel. This is a problem when you need to do some processing prior to navigation.

The solution I came up with mildly violates MVVM, but as little as possible - I pass in a reference to the UserControl as a CommandParameter. That way the VM has an instance of the FrameworkElement that it can use to identify the frame for navigation.

In the xaml:
<UserControl x:Class="WpfApplication1.UserControls.Page1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mui="http://firstfloorsoftware.com/ModernUI"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding Source={StaticResource Locator}, Path=Page1}"
             x:Name="Page1View">
<mui:ModernButton Command="{Binding ButtonClickedCommand}" CommandParameter="{Binding ElementName=Page1View}">
            Click Me
        </mui:ModernButton>
</UserControl>
In the ViewModel:
namespace WpfApplication1.ViewModel
{
    public class Page1ViewModel : ViewModelBase
    {
        public Page1ViewModel()
        {

            this.ButtonClickedCommand = new RelayCommand<FrameworkElement>(param => this.ProcessButtonClick(param));
        }

        public RelayCommand<FrameworkElement> ButtonClickedCommand { get; private set; }

        public void ProcessButtonClick(FrameworkElement userControl)
        {

            var uri = new Uri("/UserControls/Page2.xaml", UriKind.Relative);

            var frame = NavigationHelper.FindFrame(null, userControl);

            frame.Source = uri;
        }

    }
}
May 16, 2013 at 4:14 AM
As mentioned by gstarbuck, many discussions exists, so there is more thanone way to skin this cat.

What I followed was more of a eventing design, its called MVVMS where the S stands for the services in your project. The approach requires you to abstract anything that is not MVVM related into a service, and on initialization of your main project, you can use your dependency injection container (MEF, Unity, etc..) to inject your correct service depending on your platform. Now you can go a bit wild with this, you can build a NavigationService, DialogService, DataService etc.. but you need to keep re usability in mind, if its a concern, because for each platform, you will need to create an implementation of the service for i.e windows phone, wpf, winRT etc. but very possible and cleanest MVVM design separation I've seen so far.

Have a look at the mvvmlight link here http://blog.galasoft.ch/archive/2011/01/06/navigation-in-a-wp7-application-with-mvvm-light.aspx it has a good start-up example. The mvvmlight framework is not important, as you can implement this concept with most common mvvm frameworks.

Anyway just my two cents.
May 17, 2013 at 7:00 PM
I think it MUI should implement a 'NavigationService'. what do you think? Is this possible to do?
May 20, 2013 at 3:24 PM
Yes, that's possible. Feel free to create an issue for it in the issue tracker
Jun 2, 2013 at 2:29 PM
Hi gblmarquez

Look at this post https://mui.codeplex.com/discussions/445631, should help as a start to your own navigationservice