NavigationService 抛出 NullReferenceException

发布于 2024-11-05 23:00:00 字数 784 浏览 4 评论 0原文

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

我已经使用 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 实现导航?

Using MVVM Light, I'm trying to develop a rather simple WP7 application. I've run into a problem using the navigation service. I can navigate to a page, but after pressing the back button I can't navigate to the same page again. NavigationService throws a NullReferenceException.

I have implemented my navigation using Messaging from the GalaSoft.MvvmLight.Messaging namespace. All my views inherits from a customized PhoneApplicationPage base class that registrers a listener on "NavigationRequest":

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

From my view models I post Uri's to this listener:

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

Like i said, this works except when navigating after pressing the Back button.
Why is this and how can I solve it?

Is there a better way to implement navigation using MVVM Light?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蒲公英的约定 2024-11-12 23:00:00

我也在使用 MVVM Light。我有一个名为 PageConductor 的类,它基于 Microsoft 的 John Papa(Silverlight MVP)使用的类。这是我使用的 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 构造函数中,我有这个,它在我的 PageConductor 服务中创建我的 ContentFrame 的实例。:

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

然后,我使用依赖项注入将我的 PageConductor 服务的实例实例化到我的 MainPage ViewModel 中。这是我的 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; }
}

我对前进/后退按钮没有任何问题。

I'm using MVVM Light as well. I have a class called PageConductor, which is based on what John Papa (Silverlight MVP) from Microsoft uses. Here's the PageConductor Service I use

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();
    }
}

In my MainPage.xaml.cs constructor, I have this, which creates an instance of my ContentFrame in my PageConductor service.:

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

I then use dependency injection to instantiate an instance of my PageConductor Service into my MainPage ViewModel. Here is my MainViewModel class:

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");
    }

Notice the instance of my PageConductorService as a parameter in my MainViewModel constructor method. I pass this in via my 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

For further reference, my Messages.FrameMessage class is simply:

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

I've had no issues with forward/back buttons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文