C# WPF NavigationServiceでの画面遷移時に例外が発生する

前提

C# (WPF)に関する質問です。
一定時間操作がない場合に、別の画面に遷移する機能を実装しています。(スクリーンセーバー機能)

1: TimerTestページで無操作の時間が5秒に達すると、ScreenSaverTestページに遷移します。
2: ScreenSaverページ中央のNavigationボタンを押下すると、再度TimerTestページに遷移します。

以上を何回も繰り返して動きを確認する想定でした。

実際にやってみると、1度目の画面遷移は問題ないようですが、2度目の画面遷移からは例外が発生します。
TimerTestページの41行目にブレークポイントを登録してみると、2度目の遷移処理の際、NavigationServiceがnullであることが気になりました。

原因がわからず、知恵をお借りしたいです。

発生している問題・エラーメッセージ

System.NullReferenceException: 'Object reference not set to an instance of an object.' System.Windows.Controls.Page.NavigationService.get が null を返しました。

該当のソースコード

TimerTest.xaml(遷移元)

XAML

1<Page x:Class="Test.TimerTest" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:Test" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800" 9 Title="TimerTest" 10 Loaded="Page_Loaded"> 11 12 <Canvas> 13 <Label Content="TimerTestPage" 14 Height="30" Width="200" 15 Background="White"/> 16 </Canvas> 17</Page>

ScreenSaverTest.xaml.cs

C#

1using System;2using System.Collections.Generic;3using System.Diagnostics;4using System.Text;5using System.Windows;6using System.Windows.Controls;7using System.Windows.Data;8using System.Windows.Documents;9using System.Windows.Input;10using System.Windows.Interop;11using System.Windows.Media;12using System.Windows.Media.Imaging;13using System.Windows.Navigation;14using System.Windows.Shapes;15using System.Windows.Threading;16 17namespace Test 18{19 /// <summary>20 /// TimerTest.xaml の相互作用ロジック21 /// </summary>22 public partial class TimerTest : Page 23 {24 private DispatcherTimer _timer = new DispatcherTimer();25 26 public TimerTest()27 {28 InitializeComponent();29 _timer.Interval = TimeSpan.FromSeconds(5);30 _timer.Tick += _timer_Tick;31 _timer.Start();32 }33 private void Page_Loaded(object sender, RoutedEventArgs e)34 {35 SetAddHook();36 37 }38 private void _timer_Tick(object sender, EventArgs e)39 {40 var screenSaverTest = new ScreenSaverTest();41 NavigationService.Navigate(screenSaverTest);42 }43 44 45 /// <summary>46 /// マウスカーソルが移動したことを示すウィンドウメッセージ。47 /// </summary>48 private const int WmMouseMove = 0x0200;49 50 /// <summary>51 /// マウス左ボタンが押されたことを示す。ウィンドウメッセージ。52 /// </summary>53 private const int WmMouseLeftButtonDown = 0x0201;54 55 private void SetAddHook()56 {57 var parenWindow = Window.GetWindow(this);58 HwndSource source = HwndSource.FromHwnd(new 59 WindowInteropHelper(parenWindow).Handle);60 source.AddHook(WindowProc);61 }62 63 private IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)64 {65 switch (msg)66 {67 case WmMouseMove:68 _timer.Stop();69 _timer.Start();70 break;71 72 case WmMouseLeftButtonDown:73 _timer.Stop();74 _timer.Start();75 break;76 77 default:78 break;79 }80 return hwnd;81 }82 }83}

ScreenSaverTest.xaml

XAML

1<Page x:Class="Test.ScreenSaverTest" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:local="clr-namespace:Test" 7 mc:Ignorable="d" 8 d:DesignHeight="450" d:DesignWidth="800" 9 Title="ScreenSaverTest"> 10 11 <Canvas> 12 <Label Content="ScreenSaverTestPage" 13 Height="30" Width="200" 14 Background="White"/> 15 <Button x:Name="Button" 16 Content="NaVigation" 17 Height="50" Width="200" 18 Canvas.Left="300" Canvas.Top="200" 19 Click="Button_Click"/> 20 </Canvas> 21</Page>

ScreenSaverTest.xaml.cs

C#

1using System;2using System.Collections.Generic;3using System.Text;4using System.Windows;5using System.Windows.Controls;6using System.Windows.Data;7using System.Windows.Documents;8using System.Windows.Input;9using System.Windows.Media;10using System.Windows.Media.Imaging;11using System.Windows.Navigation;12using System.Windows.Shapes;13 14namespace Test 15{16 /// <summary>17 /// ScreenSaverTest.xaml の相互作用ロジック18 /// </summary>19 public partial class ScreenSaverTest : Page 20 {21 public ScreenSaverTest()22 {23 InitializeComponent();24 }25 26 private void Button_Click(object sender, RoutedEventArgs e)27 {28 var timerTestPage = new TimerTest();29 NavigationService.Navigate(timerTestPage);30 }31 }32}

補足情報(FW/ツールのバージョンなど)

Visual Studio 2022
C#10.0
WPF

コメントを投稿

0 コメント