NavigationService создает исключение NullReferenceException - PullRequest
2 голосов
/ 08 мая 2011

Используя MVVM Light, я пытаюсь разработать довольно простое приложение WP7.Я столкнулся с проблемой при использовании службы навигации.Я могу перейти на страницу, но после нажатия кнопки «Назад» я не могу перейти на ту же страницу снова.NavigationService генерирует исключение NullReferenceException.

Я реализовал навигацию, используя Messaging из пространства имен GalaSoft.MvvmLight.Messaging.Все мои представления наследуются от настроенного базового класса PhoneApplicationPage, который регистрирует слушателя по «NavigationRequest»:

public class PhoneApplicationPage : Microsoft.Phone.Controls.PhoneApplicationPage
{
    public PhoneApplicationPage() : base()
    {
        Messenger.Default.Register<Uri>(this, "NavigationRequest", (uri) => NavigationService.Navigate(uri));
    }
}

Из моделей моего представления я публикую Uri для этого слушателя:

SendNavigationRequestMessage(new Uri("/View/AppSettingsView.xaml", UriKind.Relative));

сказал, что это работает, кроме как при навигации после нажатия кнопки Назад.Почему это так и как я могу это решить?

Есть ли лучший способ реализовать навигацию с использованием MVVM Light?

1 Ответ

0 голосов
/ 09 мая 2011

Я также использую MVVM Light. У меня есть класс под названием PageConductor, который основан на том, что использует Джон Папа (Silverlight MVP) от Microsoft. Вот служба PageConductor, которую я использую

public class PageConductor : IPageConductor
{
    protected Frame RootFrame { get; set; }

    public PageConductor()
    {
        Messenger.Default.Register<Messages.FrameMessage>(this, OnReceiveFrameMessage);
    }
    public void DisplayError(string origin, Exception e, string details)
    {
        string description = string.Format("Error occured in {0}. {1} {2}", origin, details, e.Message);
        var error = new Model.Error() { Description = description, Title = "Error Occurred" };
        Messenger.Default.Send(new Messages.ErrorMessage() { Error = error });
    }

    public void DisplayError(string origin, Exception e)
    {
        DisplayError(origin, e, string.Empty);
    }
    private void OnReceiveFrameMessage(Messages.FrameMessage msg)
    {
        RootFrame = msg.RootFrame;
    }
    private void Go(string path, string sender)
    {
        RootFrame.Navigate(new Uri(path, UriKind.Relative));
    }
    public void GoBack()
    {
        RootFrame.GoBack();
    }
}

В моем конструкторе MainPage.xaml.cs у меня есть это, которое создает экземпляр моего ContentFrame в моей службе PageConductor .:

Messenger.Default.Send(new Messages.FrameMessage() { RootFrame = ContentFrame });

Затем я использую внедрение зависимостей для создания экземпляра моей службы PageConductor в моей модели представления MainPage. Вот мой класс MainViewModel:

protected Services.IPageConductor PageConductor { get; set; }
    public RelayCommand<string> NavigateCommand { get; set; }

    public MainViewModel(Services.IPageConductor pageConductor)
    {

        PageConductor = pageConductor;
        RegisterCommands();
    }
    private void RegisterCommands()
    {
        NavigateCommand = new RelayCommand<string>(
            (source) => OnNavigate(source));

    }
    private void OnNavigate(string sender)
    {
        PageConductor.GoToView(sender, "main");
    }

Обратите внимание на экземпляр моего PageConductorService как параметр в моем методе конструктора MainViewModel. Я передаю это через мой ViewModelLocator:

private readonly TSMVVM.Services.ServiceProviderBase _sp;
public ViewModelLocator()
{
    _sp = Services.ServiceProviderBase.Instance;
CreateMain(_sp);
}
        #region MainPageViewModel
    public static MainViewModel MainStatic
    {
        get
        {
            Services.ServiceProviderBase SP = Services.ServiceProviderBase.Instance;
            if (_main == null)
            {
                CreateMain(SP);
            }

            return _main;
        }
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
         "CA1822:MarkMembersAsStatic",
         Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return MainStatic;
        }
    }

    public static void ClearMain()
    {
        _main.Cleanup();
        _main = null;
    }

    public static void CreateMain(Services.ServiceProviderBase SP)
    {
        if (_main == null)
        {
            _main = new MainViewModel(SP.PageConductor);
        }
    }
    #endregion

Для дальнейшего использования мой класс Messages.FrameMessage просто:

internal class FrameMessage
{
    public Frame RootFrame { get; set; }
}

У меня не было проблем с кнопками вперед / назад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...