前提
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
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2023/03/09 11:31 編集
2023/03/09 12:13