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.

braunbaer
  • 1,113
  • 1
  • 9
  • 20
  • Are you sure you get the exception there, and not on the next line? `CurrentItem` and hence `currentSerie` might well be `null`. – Clemens Apr 04 '12 at 08:32
  • @Clemens well thats what VS2010 is telling me. Also i tried to run it without the Console output and got the same error – braunbaer Apr 04 '12 at 08:38
  • And what exactly is `null` there? Do you have the stack trace? – Clemens Apr 04 '12 at 08:54
  • @Clemens here you go http://pastebin.com/qzzhbCvt sry for the german output – braunbaer Apr 04 '12 at 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 Apr 04 '12 at 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 Apr 04 '12 at 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 Apr 04 '12 at 09:26
  • this.NavigationService is null – braunbaer Apr 04 '12 at 09:31
  • And is it a new instance of `Page1` that you are in at the breakpoint? – Clemens Apr 04 '12 at 09:40

1 Answers1

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.

Marat Khasanov
  • 3,808
  • 19
  • 22
  • 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 Apr 04 '12 at 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 Apr 04 '12 at 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? thx – braunbaer Apr 04 '12 at 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 Apr 04 '12 at 13:15