NullreferenceException when using NavigationServic

2019-09-07 07:25发布

I'm encountering a problem with my WP7 app:

I'm trying to make a login page prompt only when the app can't detect any stored username or password values; however, I keep running into a NullReferenceException when I try to navigate to my login page.

My code looks like this, and it's in the contructor:

if (!checkLogin())
    {
        NavigationService.Navigate(new Uri("/LoginPage.xaml", UriKind.Relative));
    }

And checkLogin is just a function that returns either true or false depending or not the isolated storage settings are set correctly.

Anybody have any suggestions?

Thanks.

1条回答
萌系小妹纸
2楼-- · 2019-09-07 08:12

Here is what i think you want to do (From Peter Torr's blog).

If you need more clarification here is a piece of code to illustrate that. Assume there are 2 pages A.XAML and B.xaml and you would want to detect in whether to load A.xaml or B.xaml based on checking some login credentials which is stored in the IsolatedStorage,

in App.xaml.cs of your project overwrite public App() with:

    public App()
    {
        // Global handler for uncaught exceptions. 
        UnhandledException += Application_UnhandledException;

        // Standard Silverlight initialization
        InitializeComponent();

        // Phone-specific initialization
        InitializePhoneApplication();

        // Show graphics profiling information while debugging.
        if (System.Diagnostics.Debugger.IsAttached)
        {
            // Display the current frame rate counters.
            Application.Current.Host.Settings.EnableFrameRateCounter = true;

            // Show the areas of the app that are being redrawn in each frame.
            //Application.Current.Host.Settings.EnableRedrawRegions = true;

            // Enable non-production analysis visualization mode, 
            // which shows areas of a page that are handed off to GPU with a colored overlay.
            //Application.Current.Host.Settings.EnableCacheVisualization = true;

            // Disable the application idle detection by setting the UserIdleDetectionMode property of the
            // application's PhoneApplicationService object to Disabled.
            // Caution:- Use this under debug mode only. Application that disables user idle detection will continue to run
            // and consume battery power when the user is not using the phone.
            PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
        }

        RootFrame.Navigating += new NavigatingCancelEventHandler(RootFrame_Navigating);
    }

    void RootFrame_Navigating(object sender, NavigatingCancelEventArgs e)
    {
        if (e.Uri.ToString().Contains("/MainPage.xaml") != true)
        {
            return;
        }
        e.Cancel = true;
        RootFrame.Dispatcher.BeginInvoke(delegate
        {
            if (System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.Contains("Login_Credentials"))
            {
                RootFrame.Navigate(new Uri("/B.xaml", UriKind.Relative));
            }
            else
            {
                RootFrame.Navigate(new Uri("/A.xaml", UriKind.Relative));
            }
        });
    }

Then create the 2 dummy pages A.xaml and B.xaml so that for A.xaml you have some logic for saving the login credentials (in this case just a boolean flag):

A.XAML:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <!--TitlePanel contains the name of the application and page title-->
    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="A Page" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <!--ContentPanel - place additional content here-->
    <StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Button Content="Save Login Creds" Click="SaveLoginCreds"/>
    </StackPanel>
</Grid>

A.XAML.cs:

private void SaveLoginCreds(object sender, RoutedEventArgs e)
{
    System.IO.IsolatedStorage.IsolatedStorageSettings.ApplicationSettings.Add("Login_Credentials", true);
}

Now, when you run the application for the first time, it will load A.xaml because it could not find any login credentials. Then if you click on the button, it will save the login credentials data in IsolatedStorage. Next time, you start the app it will load B.xaml because it detected the login credentials.

I hope this helps.

查看更多
登录 后发表回答