前提
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 コメント