首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NavigationService抛出NullReferenceException

NavigationService抛出NullReferenceException
EN

Stack Overflow用户
提问于 2011-05-09 01:27:59
回答 1查看 1.5K关注 0票数 2

使用MVVM Light,我正在尝试开发一个相当简单的WP7应用程序。我在使用导航服务时遇到了一个问题。我可以导航到一个页面,但是在按下back按钮之后,我不能再次导航到同一页面。NavigationService抛出一个NullReferenceException。

我已经使用来自GalaSoft.MvvmLight.Messaging名称空间的消息实现了我的导航。我的所有视图都继承自一个自定义的PhoneApplicationPage基类,该类在“NavigationRequest”上注册一个监听器:

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

从我的视图模型中,我将Uri发布到此侦听器:

代码语言:javascript
复制
SendNavigationRequestMessage(new Uri("/View/AppSettingsView.xaml", UriKind.Relative));

正如我所说的,这是有效的,除非在按下后退按钮后导航。为什么会这样?我该如何解决它?

有没有更好的方式使用MVVM Light实现导航?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-09 06:21:08

我也在使用MVVM Light。我有一个名为PageConductor的类,它是基于微软的John Papa (Silverlight MVP)使用的。下面是我使用的PageConductor服务

代码语言:javascript
复制
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构造函数中,我有这个,它在我的PageConductor服务中创建了我的ContentFrame的一个实例。

代码语言:javascript
复制
Messenger.Default.Send(new Messages.FrameMessage() { RootFrame = ContentFrame });

然后,我使用依赖注入将PageConductor服务的一个实例实例化到我的MainPage ViewModel中。下面是我的MainViewModel类:

代码语言:javascript
复制
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");
    }

请注意,在我的MainViewModel构造函数方法中,我的PageConductorService实例是一个参数。我通过我的ViewModelLocator传入以下代码:

代码语言:javascript
复制
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类是:

代码语言:javascript
复制
internal class FrameMessage
{
    public Frame RootFrame { get; set; }
}

我在使用前进/后退按钮时没有遇到任何问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5929046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档