NullPointerException after going back in a NavigationWindow

Go To StackoverFlow.com

0

thats my navigation window

<NavigationWindow x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="800" Width="600" Source="Page1.xaml">

thats my page1

<Page x:Class="WpfApplication1.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" 
  mc:Ignorable="d" 
  d:DesignHeight="600" d:DesignWidth="800"
Title="Page1" Name="IndexPage">

<ListView Name="myListView" ItemsSource="{Binding ElementName=IndexPage, Path=SeriesCollection}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" IsSynchronizedWithCurrentItem="True" SelectionChanged="handleSelected">
    <ListView.ItemsPanel >
        <ItemsPanelTemplate>
            <WrapPanel>
            </WrapPanel>
        </ItemsPanelTemplate>            
    </ListView.ItemsPanel>
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel >
                <Image Width="214" Height="317" Source="{Binding Image}"/>
                <Label Content="{Binding Name}" />
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Page 2 is just en empty skeleton

code behind

namespace WpfApplication1
{
/// <summary>
/// Interaktionslogik für Page1.xaml
/// </summary>
public partial class Page1 : Page
{
    private ObservableCollection<Series> _series =
      new ObservableCollection<Series>();

    public ObservableCollection<Series> SeriesCollection
    {
        get { return _series; }
    }

    public Page1()
    {
        InitializeComponent();

        DirectoryInfo baseDir = new DirectoryInfo(@"C:\Serien");
        DirectoryInfo[] dirs = baseDir.GetDirectories();
        foreach (DirectoryInfo dir in dirs)
        {
            Series serie = new Series(dir);
            Console.WriteLine("adding " + serie.Name);
            _series.Add(serie);
        }

        Console.WriteLine(_series.Count);
    }

    public void handleSelected(object sender, RoutedEventArgs args)
    {
        Series currentSerie = (Series) myListView.Items.CurrentItem;

        Page2 page = new Page2();
        this.NavigationService.Navigate(page);

        Console.WriteLine(currentSerie.Name);
        Console.WriteLine(currentSerie.GetType());
        Console.WriteLine(currentSerie.ToString());
    }
}
}

so i click on an item to trigger the SelectionChanged Event to handle it in SelectionChanged where i navigate to page2 , so far so good.

then i use the back button from the navigation window and get stuck with an NullpointerException at

this.NavigationService.Navigate(page);

i dont even know why this method is triggered. So obviosly i am doing something stupid. Pls tell me what it is. Thanks for your time and affort.

2012-04-04 06:47
by braunbaer
Are you sure you get the exception there, and not on the next line? CurrentItem and hence currentSerie might well be null - Clemens 2012-04-04 08:32
@Clemens well thats what VS2010 is telling me. Also i tried to run it without the Console output and got the same erro - braunbaer 2012-04-04 08:38
And what exactly is null there? Do you have the stack trace - Clemens 2012-04-04 08:54
@Clemens here you go http://pastebin.com/qzzhbCvt sry for the german outpu - braunbaer 2012-04-04 09:10
Kein Problem. Sorry, but stack trace doesn't help. Try setting a breakpoint at that line to find out what is null - Clemens 2012-04-04 09:20
i will check what you are asking for. in the meantime, do you have any idea why this function is executed at all? why does "navigation.back" trigger an "selectionChanged" event - braunbaer 2012-04-04 09:24
Sorry, no idea. But it sounds strange. Is it possible that navigating back somehow leads to creating a new instance of Page1 - Clemens 2012-04-04 09:26
this.NavigationService is nul - braunbaer 2012-04-04 09:31
And is it a new instance of Page1 that you are in at the breakpoint - Clemens 2012-04-04 09:40


0

The problem here is that you handle the wrong event. I assume that you want to open Page2 by clicking a ListViewItem. Therefore you should use mouse events instead of SelectionChanged.

For example, you can subscribe to StackPanel MouseDown event in your DataTemplate:

<DataTemplate>
    <StackPanel Background="Transparent"
                MouseDown="StackPanel_MouseDown">
        <Image Width="214" Height="317" Source="{Binding Image}"/>
        <Label Content="{Binding Name}"/>
    </StackPanel>
</DataTemplate>

You can access clicked Series using the following:

private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
{
    var currentSerie = (Series)((StackPanel)sender).DataContext;
    ...
}

UPD If you need a real click, you may use a trick like this:

<DataTemplate>
    <Button Click="Button_Click">
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <ContentPresenter/>
            </ControlTemplate>
        </Button.Template>
        <StackPanel Background="Transparent">
            <Image Width="214" Height="317" Source="{Binding Image}"/>
            <Label Content="{Binding Name}"/>
        </StackPanel>
    </Button>
</DataTemplate>

We use a Button like a view-model which is able to handle clicks.

2012-04-04 09:33
by Marat Khasanov
this works. But is it realy good practice to use the mouseDown event as a click event? should i use a button in the stackPanel to have a real click event?

also i still dont know why SelectionChanged is a bad event for this type of flow (besides that it does not work ;- )

thx you very much, if there wount be a better answer soon i will accept yours - braunbaer 2012-04-04 11:10

The purpose of SelectionChanged is to react when SelectedItem property was changed. There are many ways how it can be done. The user may click on ListViewItem or use keyboard keys, the code can toggle selection by assigning another value to SelectedItem property. Are you sure that you want to open Page2 in all of these cases? That's why SelectionChanged is bad for you. I agree that adding a button is nicer if click is needed, so I'll update my answer. A better solution should use a Command instead of event handler - Marat Khasanov 2012-04-04 11:56
thx for your help. I implemented the "open" command as i think it fits good into the context. But then "sender" changed to Page and i falled back to myListView.Items.CurrentItem to get the current selection. So do i need the button anymore? as i am using command and not the click event? th - braunbaer 2012-04-04 12:31
Use CommandParameter instead of "sender". Have a look: http://stackoverflow.com/questions/9963594/accessing-to-a-listview-at-runtime-to-update-an-item/9966599#9966599 You can bind CommandParameter like {Binding} to send clicked Series directly to handler - Marat Khasanov 2012-04-04 13:15
Ads