を間違って使用しているのかもしれませんが、が使用され、結果がモデルに渡されるOpenFileDialog
たびに、未処理の例外が抑制されていることがわかりました。OpenFileDialog
AppDomain.CurrentDomain.UnhandledException
通常、未処理の例外を処理するためにイベントをフックしますが、使用後に発生した例外はOpenFileDialog
すべて飲み込まれます。
以下は、この動作を再現する例です。この例を実行すると、コード ビハインドで例外がスローされ、プロパティがApp.xaml.csShellModel.ThrowException
のハンドラーによって正しくキャッチされていることがわかります。ただし、を使用した後にプロパティUnHandledException
でスローされる例外は抑制されています。ShellModel.OpenFile
OpenFileDialog
これらの例外が抑制されるのはなぜですか?
App.xaml.cs
using System;
using System.Text;
using System.Windows;
namespace ExceptionTest
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup( StartupEventArgs e )
{
base.OnStartup( e );
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
}
private void OnUnhandledException( object sender, UnhandledExceptionEventArgs e )
{
var ex = e.ExceptionObject as Exception;
if( ex == null )
{
MessageBox.Show( string.Format( "Null Exception: {0}", e ) );
return;
}
var sb = new StringBuilder();
sb.AppendLine( "An unhandled exception was encountered. Terminating now." );
sb.AppendLine();
sb.AppendLine( "Exception:" );
sb.AppendLine( ex.Message );
MessageBox.Show( sb.ToString(), "Whoops...", MessageBoxButton.OK, MessageBoxImage.Error );
Environment.Exit( 1 );
}
}
}
Shell.xaml
<Window x:Class="ExceptionTest.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Model="clr-namespace:ExceptionTest"
Title="Exception Test" Height="350" Width="350" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<Model:ShellModel x:Name="Model" />
</Window.DataContext>
<StackPanel Orientation="Vertical" VerticalAlignment="Stretch">
<Button
Click="OnCodeBehind" Margin="20"
Content="Exception from code behind" Height="25" Width="250" />
<Button
Click="OnThrowExeption" Margin="20"
Content="Exception from Model" Height="25" Width="250" />
<Button
Click="OnFindFile" Margin="20"
Content="Exception from OpenFileDialog" Height="25" Width="250" />
<Label Content="{Binding OpenFile, Mode=TwoWay}" x:Name="OpenFile"
Height="28" HorizontalAlignment="Left" VerticalAlignment="Top" Width="Auto" />
</StackPanel>
</Window>
Shell.xaml.cs / モデル
using System;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Windows;
using Microsoft.Win32;
namespace ExceptionTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class Shell : Window
{
private OpenFileDialog OpenDialog { get; set; }
public Shell()
{
InitializeComponent();
OpenDialog = new OpenFileDialog();
string path = new Uri( Assembly.GetExecutingAssembly().CodeBase ).LocalPath;
OpenDialog.InitialDirectory = Path.GetDirectoryName( path );
OpenDialog.Multiselect = false;
OpenDialog.Title = "Find File";
OpenDialog.RestoreDirectory = true;
}
private void OnCodeBehind( object sender, RoutedEventArgs e )
{
throw new Exception( "Exception from Code Behind." );
}
private void OnThrowExeption( object sender, RoutedEventArgs e )
{
Model.ThrowException = "Test";
e.Handled = true;
}
private void OnFindFile( object sender, RoutedEventArgs e )
{
OpenDialog.ShowDialog( this );
string fileName = OpenDialog.FileName;
if( !string.IsNullOrEmpty( fileName ) )
{
OpenDialog.InitialDirectory = Path.GetDirectoryName( fileName );
OpenFile.Content = fileName;
}
}
}
public class ShellModel : INotifyPropertyChanged
{
private string _throwException;
public string ThrowException
{
get { return _throwException; }
set
{
_throwException = value;
NotifyPropertyChanged( "ThrowException" );
throw new Exception( "Exception from Model." );
}
}
private string _openFile;
public string OpenFile
{
get { return _openFile; }
set
{
_openFile = value;
NotifyPropertyChanged( "OpenFile" );
throw new Exception( "Exception from Model after using OpenFileDialog." );
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged( String info )
{
if( PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( info ) );
}
}
}
}
解像度
回答で述べたように、これは OpenFileDialog の問題ではなく、データ バインディングの問題です。
Bradley の回答と Hans の可能性のある重複リンクは、いくつかの優れた情報を示しています。リンク/記事は、私が思いついた解決策を提供しませんでした.re:フックできる別の例外があることがわかりました:AppDomain.CurrentDomain.FirstChanceException
my の修正版は次のApp.Xaml.cs
とおりです。
protected override void OnStartup( StartupEventArgs e )
{
base.OnStartup( e );
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
// The FirstChanceException will catch binding errors
AppDomain.CurrentDomain.FirstChanceException += OnFirstChanceException;
}
private void OnFirstChanceException( object sender, FirstChanceExceptionEventArgs e )
{
// do stuff
}
バインディング エラーがキャッチされました。