2009-03-03 7 views
1

プロパティセットのアクセサからスローされた例外が、グローバル例外ハンドラによって捕捉されないという問題が発生しています。データバインドされたnumericupdown 'hiding'例外がバインドされたプロパティでスローされました

私は大きなアプリケーションで問題を抱えていましたが、問題をトラブルシューティングした後、簡単なプロジェクトで問題を再現しました。

以下はコードと動作です。誰かがこの動作を説明してください、そして、どのようにして、グローバルイベントハンドラによって捕捉されるべき例外のための適切な結果を達成するために適切にコード化するべきですか?私はプログラムが確かにこの時点際に破壊される '新しい例外ArgumentNullExceptionを投げる' 行にブレークポイントを設定した場合

//Program.cs - Wire up global exception handling 
static class Program 
{ 
[STAThread] 
static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    Application.Run(new Form1()); 
} 

static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 
{ 
    MessageBox.Show("Exception occured : " + e.Exception.Message); 
} 

*

//In main form create instance of class containing bound property and setup databinding 
//to numericUpDown control 
private void Form1_Load(object sender, EventArgs e) 
{ 
    _car = new Car(); 
    _car.NumberOfWheels = 4; 
    numericUpDown1.DataBindings.Add(new Binding("Value", _car, "NumberOfWheels", true, DataSourceUpdateMode.OnPropertyChanged)); 
} 

*

public int NumberOfWheels 
{ 
    get { return _numberOfWheels; } 
    set 
    { 
     if (value < 4) 
      //Throw some exception 
      throw new ArgumentNullException("Argument null exception trigger in Number Of Wheels property"); 

     _numberOfWheels = value; 
    } 

}

私は、NumberOfWheelsプロパティにバインドされているnumericUpDownコントロールの値を変更します。ただし、これが例外がスローされたかどうかを検出する唯一の方法です。例外がスローされた、つまりグローバル例外ハンドラで捕捉されていないというメッセージは、UIを介して表示されません。

ボタンをクリックしてプロパティの値を変更すると、例外がスローされ、メッセージボックスが表示された状態でハンドラで捕捉されます。

私には何が欠けていますか?

答えて

0

バインディングは、例外を「飲み込む」または「隠す」でしょう。おそらく、これはよりフォールトトレラントなものです。

BindingCompleteイベントをリッスンし、BindingCompleteEventArgs BindingCompleteStateプロパティでBindingCompleteStateを確認する必要があります。その値がBindingCompleteState.Exceptionである場合、BindingCompleteEventArgs ExceptionプロパティにはスローされたExceptionが含まれます。

public Form1() 
    { 
     InitializeComponent(); 

     Binding binding = new Binding("Value", _car, "NumWheels", true, DataSourceUpdateMode.OnPropertyChanged); 
     numericUpDown1.DataBindings.Add(binding); 
     binding.BindingComplete += new BindingCompleteEventHandler(binding_BindingComplete); 

    } 

    void binding_BindingComplete(object sender, BindingCompleteEventArgs e) 
    { 
     if (e.BindingCompleteState == BindingCompleteState.Exception) 
     { 
      throw e.Exception; 
     } 
    } 
0

非常に有用だったと私はデータバインディングの上に、さらに私の知識を広げる許可おかげMufaka

。ただし、例外はまだグローバル例外ハンドラによって捕捉されていません。 binding_BindingCompleteの最後の '}'でコードが破損し、「ArgumentNullExceptionがユーザーコードによって未処理です」というメッセージが表示されます。

あなたが説明するように、私はそれが仕事を得ることができる唯一の方法は、私が

を設定した場合
binding.FormattingEnabled = false; 

ですが、これは自分の問題だ持っているように見えます。

私は今あなたのアプローチをとると思いますが、例外を再びスローする代わりに、メッセージボックスを表示して元の値に戻します。

このハンドラは、データバインドされたすべてのコントロールに使用できます。

関連する問題