【问题标题】:NullPointerException after going back in a NavigationWindow返回 NavigationWindow 后出现 NullPointerException
【发布时间】:2012-04-04 06:47:13
【问题描述】:

这是我的导航窗口

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

这是我的页面1

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

第 2 页只是一个空骨架

后面的代码

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

所以我单击一个项目以触发 SelectionChanged 事件以在我导航到 page2 的 SelectionChanged 中处理它,到目前为止一切顺利。

然后我使用导航窗口中的后退按钮并在

处遇到 NullpointerException
this.NavigationService.Navigate(page);

我什至不知道为什么会触发此方法。所以很明显我在做一些愚蠢的事情。请告诉我它是什么。感谢您的时间和努力。

【问题讨论】:

  • 你确定你在那里得到了异常,而不是在下一行? CurrentItem 因此currentSerie 很可能是null
  • @Clemens 这就是 VS2010 告诉我的。我也尝试在没有控制台输出的情况下运行它并得到相同的错误
  • null 到底是什么?你有堆栈跟踪吗?
  • @Clemens 你去pastebin.com/qzzhbCvt sry 德国输出
  • 凯因问题。对不起,但堆栈跟踪没有帮助。尝试在该行设置断点以找出 null 是什么。

标签: c# wpf nullpointerexception navigationwindow


【解决方案1】:

这里的问题是你处理了错误的事件。我假设您想通过单击 ListViewItem 打开 Page2。因此,您应该使用鼠标事件而不是 SelectionChanged。

例如,您可以在 DataTemplate 中订阅 StackPanel MouseDown 事件:

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

您可以使用以下方式访问点击的系列:

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

UPD如果你需要真正的点击,你可以使用这样的技巧:

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

我们使用像视图模型这样能够处理点击的按钮。

【讨论】:

  • 这行得通。但是将 mouseDown 事件用作单击事件真的是一种好习惯吗?我应该使用 stackPanel 中的按钮来进行真正的点击事件吗?另外我仍然不知道为什么 SelectionChanged 对于这种类型的流程来说是一个坏事件(除了它不起作用;-)非常感谢你,如果很快没有更好的答案,我会接受你的。
  • SelectionChanged 的​​目的是在 SelectedItem 属性更改时做出反应。有很多方法可以做到。用户可以单击 ListViewItem 或使用键盘键,代码可以通过为 SelectedItem 属性分配另一个值来切换选择。您确定要在所有这些情况下打开 Page2 吗?这就是为什么 SelectionChanged 对您不利的原因。我同意如果需要单击添加按钮会更好,所以我会更新我的答案。更好的解决方案应该使用命令而不是事件处理程序。
  • 感谢您的帮助。我实施了“打开”命令,因为我认为它很适合上下文。但是随后“发件人”更改为 Page 并且我回退到 myListView.Items.CurrentItem 以获取当前选择。那我还需要这个按钮吗?因为我使用的是命令而不是点击事件?谢谢
  • 使用 CommandParameter 而不是“sender”。看看:stackoverflow.com/questions/9963594/… 你可以像 {Binding} 这样绑定 CommandParameter 以将点击的系列直接发送到处理程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 2021-12-10
相关资源
最近更新 更多