2017-07-21 18 views
0

私は、メインウィンドウと子ウィンドウを持つ単純なWPFアプリケーションを持っています。子ウィンドウはクローズ時に確認を求める必要があります。にメッセージボックス]ダイアログボックスの所有者を置き換えるWPF:MessageBox.Show in Window.OnClosing復元ウィンドウのクラッシュ

System.InvalidOperationException occurred 
    HResult=0x80131509 
    Message=Cannot set Visibility to Visible or call Show, ShowDialog, Close, or WindowInteropHelper.EnsureHandle while a Window is closing. 
    Source=PresentationFramework 
    StackTrace: 
    at System.Windows.Window.VerifyNotClosing() 
    at System.Windows.Window.CoerceVisibility(DependencyObject d, Object value) 
    at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, Object controlValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, Boolean skipBaseValueChecks) 
    at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType) 
    at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal) 
    at System.Windows.Window.UpdateVisibilityProperty(Visibility value) 
    at System.Windows.Window.WmShowWindow(IntPtr wParam, IntPtr lParam) 
    at System.Windows.Window.WindowFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) 
    at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) 

場合:クリックして「デスクトップの表示」タスクバーにして、「表示開いているウィンドウを」クリックし、アプリは例外でクラッシュしたことになる場合

public partial class MainWindow : Window 
    { 
    Window childWindow; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     Loaded += MainWindow_Loaded; 
    } 

    private void MainWindow_Loaded(object sender, RoutedEventArgs e) 
    { 
     childWindow = new Window(); 
     childWindow.Owner = this; 
     childWindow.Closing += ChildWindow_Closing; 
     childWindow.Show(); 
    } 

    private void ChildWindow_Closing(object sender, CancelEventArgs e) 
    { 
     MessageBox.Show(childWindow, "Close child window?"); 
    } 
    } 

確認ダイアログが表示されたらメインウィンドウ(これは "this")、例外は発生しません。

ここで何が間違っている可能性がありますか?

答えて

0

XAMLコードを投稿できますか?私がMainWindow.xamlで持っているものを見て、あなたのコードをMainWindow.csにコピーして、アプリケーションが準拠し、okを実行します。

<Window x:Class="WpfApp2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApp2" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Grid> 

</Grid> 

申し訳ありませんが、これはあなたの例外を再現することはできません、助けの多くではありません。

編集:私は例外の原因を見つけ、あなたのコメントに基づいて

:もう一つの思想、あなたは

childWindow.ShowDialog(); 

さらに編集を使用してみてください。 「デスクトップを表示」機能を使用する前に、タスクバーに2つのアプリウィンドウが開きました。その後、タスクバーからアプリケーションを復元しようとすると、子ウィンドウは表示されなくなります。 Windowsは、事前にクローズド・チャイルド・ウインドウを失っていると判断しているようです。したがって、メインウィンドウのサムネイルをクリックすると、アプリケーションは親ウィンドウを表示しようとしますが、閉じるプロセスで子ウィンドウが表示されている間は表示を設定できません。

これにはいくつかのアプローチがありますが、閉じている間に子ウィンドウを非表示にする方法もあります。代わりに一時的にメインウィンドウを非表示にすることもできます。これにより、例外も防止されます。前者の解決策では、子ウィンドウが閉じられると仮定すると親ウィンドウに戻ることができます(子ウィンドウが再び表示するように設定されていない場合)。子ウィンドウは子ウィンドウを表示する唯一のウィンドウのままにし、Windowsはサムネイルをタスクバーに表示させます。あなたが示したものに同じ

private void ChildWindow_Closing(object sender, CancelEventArgs e) 
     { 
      childWindow.Visibility = Visibility.Hidden; 
      MessageBox.Show(childWindow, "Close child window?"); 
     } 

または

private void ChildWindow_Closing(object sender, CancelEventArgs e) 
     { 
      Visibility = Visibility.Hidden; 
      MessageBox.Show(childWindow, "Close child window?"); 
      Visibility = Visibility.Visible; 
     } 
+0

XAMLコード。この問題を再現するには 1.アプリケーションを実行します。 2.子ウィンドウの閉じるボタン、「子ウィンドウを閉じる」のダイアログボックスを押します。出現するはずです。 3. Windowsのタスクバーを右クリックし、[デスクトップを表示]をクリックします。 4.アプリケーションをクリックして復元します - 例外が発生します。 Windows 10 .NET 4.7でこの問題を再現しました。クリーンなWindows XP(.NET 4.0のみ)でもすべてのアップデートが適用されます。 Visual Studio 2017および2015でコンパイルします。 – quio

+0

childWindow.ShowDialog()を使用する場合、例外は発生しません。しかし、それは別のケースです。 – quio

+0

さらに編集した私の答えは、これがあなたのために問題を解決できることを願っていますか? – RWo

関連する問題