2012-04-04 7 views
0

das ist mein NavigationsfensterNullpointer nachdem er in einem Navigation zurück

<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"> 

das ist meine 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 ist nur en leer Skelett

Code hinter

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

Also klicke ich auf ein Element, um das SelectionChanged Event auszulösen, um es in SelectionChanged zu behandeln, wo ich zu Seite2 navigiere, soweit so gut.

dann benutze ich die Zurück-Taste aus dem Fenster Navigation und mit einer Nullpointer bei

this.NavigationService.Navigate(page); 

ich nicht einmal wissen, warum diese Methode ausgelöst wird, stecken. Also mache ich offensichtlich etwas Dummes. Bitte sag mir was es ist. Danke für deine Zeit und deinen Lebensunterhalt.

+0

Sind Sie sicher, dass Sie die Ausnahme dort und nicht in der nächsten Zeile erhalten? 'CurrentItem' und daher' currentSerie' könnten durchaus 'null' sein. – Clemens

+0

@Clemens Nun, das ist, was VS2010 mir erzählt. Auch ich habe versucht, es ohne die Console-Ausgabe auszuführen und habe den gleichen Fehler – braunbaer

+0

Und was genau ist "null" dort? Hast du den Stack-Trace? – Clemens

Antwort

0

Das Problem hier ist, dass Sie das falsche Ereignis behandeln. Ich nehme an, dass Sie Seite2 öffnen möchten, indem Sie auf ein ListViewItem klicken. Daher sollten Sie Mausereignisse anstelle von SelectionChanged verwenden.

Zum Beispiel können Sie auf Stackpanel MouseDown- Ereignis in Ihrem Datatemplate abonnieren:

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

können Sie geklickt Access Series mit dem folgenden:

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

UPD Wenn Sie einen echten Klick benötigen , können Sie einen Trick wie folgt verwenden:

<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> 

Wir verwenden einen Button wie ein View-Modell, das mit Klicks umgehen kann.

+0

das funktioniert. Aber ist es wirklich eine gute Übung, das mouseDown-Ereignis als Klickereignis zu verwenden? Soll ich eine Schaltfläche im StackPanel verwenden, um ein echtes Klickereignis zu erhalten? auch ich weiß immer noch nicht, warum SelectionChanged ist ein schlechtes ereignis für diese art von fluss (abgesehen davon, dass es nicht funktioniert;) thx sehr sehr, wenn es wunt bald eine bessere antwort sein werde ich deins akzeptieren. – braunbaer

+0

Der Zweck von SelectionChanged ist zu reagieren, wenn SelectedItem Eigenschaft geändert wurde. Es gibt viele Möglichkeiten, wie es getan werden kann. Der Benutzer kann auf ListViewItem klicken oder Tastaturtasten verwenden. Der Code kann die Auswahl umschalten, indem er der SelectedItem-Eigenschaft einen anderen Wert zuweist. Sind Sie sicher, dass Sie Seite2 in all diesen Fällen öffnen möchten? Deshalb ist SelectionChanged schlecht für dich. Ich stimme zu, dass das Hinzufügen einer Schaltfläche angenehmer ist, wenn ein Klick erforderlich ist. Daher aktualisiere ich meine Antwort. Eine bessere Lösung sollte einen Befehl anstelle eines Ereignishandlers verwenden. –

+0

Danke für Ihre Hilfe. Ich habe den Befehl "open" implementiert, da ich denke, dass er gut in den Kontext passt. Aber dann "Absender" geändert zu Seite und ich fiel zurück zu myListView.Items.CurrentItem, um die aktuelle Auswahl zu erhalten. Also brauche ich den Knopf mehr? Wie verwende ich Befehl und nicht das Klickereignis? thx – braunbaer

Verwandte Themen