質問
2017年9月28日木曜日 3:38
Visual Studio 2010でWPFアプリケーションを開発しています。
Window1からWindow2の表示・非表示をVisibilityプロパティーでコントロールしていますが、ユーザーが「閉じる」ボタンを押すとVisibilityプロパティーの操作時に例外が発生します。
例外の内容:
System.InvalidOperationException はハンドルされませんでした。
Message=Window が閉じた後で、Visibility の設定や、Show、ShowDialog、および WindowInteropHelper.EnsureHandle の呼び出しを行うことはできません。
Windowが閉じられていることを検出するプロパティーがあるのならば、教えていただきたいです。よろしくお願い致します。
■■■<Window1:Main>
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="178" Width="432">
<Grid>
<Button Content="Button" Height="27" HorizontalAlignment="Left" Margin="50,30,0,0" Name="Button1" VerticalAlignment="Top" Width="102" />
</Grid>
</Window>
Class MainWindow
Private Property W2 As window2
Private Property b1 As Boolean
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
If b1 = True Then
W2.Visibility = Windows.Visibility.Visible
Else
W2.Visibility = Windows.Visibility.Hidden
End If
b1 = Not (b1)
End Sub
Private Sub window1_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
W2 = New window2
W2.Show()
End Sub
End Class
■■■<Window2>
<Window x:Class="window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="window2" Height="126" Width="170">
<Grid></Grid>
</Window>
(コードビハインドは無し)
すべての返信 (4)
2017年9月28日木曜日 5:38 ✅回答済み
Windowが閉じられていることを検出するプロパティーがあるのならば、教えていただきたいです。
子ウィンドウが閉じられているかどうかを検出するというより、ユーザーが子ウィンドウを閉じようとしたときに子ウィンドウを閉じるのではなく子ウィンドウを非表示にするようにするとよいかもしれませんね。
Imports System.Windows.Interop
Public Class window2
Private Sub Window1_SourceInitialized(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SourceInitialized
Dim wih As New WindowInteropHelper(Me)
Dim hs As HwndSource = HwndSource.FromHwnd(wih.Handle)
hs.AddHook(AddressOf WndProc)
End Sub
Private Function WndProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr
Const WM_SYSCOMMAND As Integer = &H112
Const SC_CLOSE As Long = &HF060L
Select Case msg
Case WM_SYSCOMMAND
If (wParam.ToInt64() And &HFFF0L) = SC_CLOSE Then
' ユーザーがウィンドウを閉じようとしたとき、ウィンドウを閉じるのをやめ非表示にする
Visibility = Visibility.Hidden
handled = True
End If
Exit Select
End Select
Return IntPtr.Zero
End Function
End Class
Class MainWindow
Private Property W2 As window2
Private Sub window1_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
W2 = New window2
W2.Show()
End Sub
Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
If W2.Visibility = Visibility.Visible Then
W2.Visibility = Visibility.Hidden
Else
W2.Visibility = Visibility.Visible
End If
End Sub
Private Sub Window_Closed(sender As Object, e As EventArgs)
W2.Close()
End Sub
End Class
2017年9月28日木曜日 3:55
Window の IsLoaded でウィンドウが閉じているか確認できるようです。
If W2.IsLoaded Then
If b1 = True Then
W2.Visibility = Visibility.Visible
Else
W2.Visibility = Visibility.Hidden
End If
b1 = Not (b1)
End If
参考サイト: https://stackoverflow.com/questions/381973/how-do-you-tell-if-a-wpf-window-is-closed
2017年9月28日木曜日 5:12
kenjinoteさん、回答ありがとうございます。
IsLoadedでウィンドウが閉じているかを読み取ることができるのは分かったのですが、一度でもcloseされてしまうと、showメソッドさえも実行できない(同じ例外が発生してしまう)ので、お答えいただいたロジックでは、処理が継続できなくなってしまいます。
「Window が閉じた後で、Visibility の設定や、Show、ShowDialog、およびWindowInteropHelper.EnsureHandle の呼び出しを行うことはできません。」
親Windowからは、子Windowの表示・非表示をコントロールできれば、それ以上のことは求めませんので、何か良い解決方法はないでしょうか。
(W2 As window2のインスタンスを削除してリコンストラクトするというのも、スマートでないのでやりたくありません。)
よろしくお願い致します。
2017年9月28日木曜日 6:27
どうもお手数をお掛けしました。
今まで、この解決方法がどうしても分からず、グシャグシャなプログラムを記述して表面上しのいでいましたが、これまでに作った子Window関連の箇所は、御教授いただいた方法で書き直す作業に入ります。御回答誠にありがとうございました。