2011-07-27 17 views
2

ドキュメントによれば、 "(FrameworkElement.SizeChanged)ActualHeightまたはActualWidthプロパティのいずれかがこの要素の値を変更すると発生します。FrameworkElement.SizeChangedがこのコードで生成されないのはなぜですか

次のテストメソッドを実行すると、MeasureChangeRootedEventは発生しませんが、MeasureとArrangeを呼び出した後、私のRectangleのActualWidthとActualHeightが更新されます。

[Test] 
    [RequiresSTA] 
    public void Test_Something() 
    { 
     bool sizeChangedRaised = false; 

     var r = new Rectangle { Width = 10, Height = 10 }; 
     r.Measure(new Size(20, 20)); 
     r.Arrange(new Rect(0, 0, 20, 20)); 

     //r.ActualWidth and r.ActualHeight are both 10 at this point. 

     r.SizeChanged += (s, e) => sizeChangedRaised = true; 

     r.Width = 5; 
     r.Height = 5; 
     r.Measure(new Size(20, 20)); 
     r.Arrange(new Rect(0, 0, 20, 20)); 

     //r.ActualWidth and r.ActualHeight are now both 5. 

     Assert.That(sizeChangedRaised);// false 
    } 

誰でもSizeChangedが発生していない理由を説明できますか?
持ち上げられるように設定できる方法はありますか?

[Test] 
    [RequiresSTA] 
    public void Test_Something() 
    { 
     bool sizeChangedRaised = false; 
     var r = new Rectangle { Width = 10, Height = 10 }; 
     r.Measure(new Size(20, 20)); 
     r.Arrange(new Rect(0, 0, 20, 20)); 
     r.SizeChanged += (s, e) => { 
      sizeChangedRaised = true; 
     }; 
     r.Width = 5; 
     r.Height = 5; 
     r.Measure(new Size(20, 20)); 
     r.Arrange(new Rect(0, 0, 20, 20)); 
     ThreadEx.Wait(1000); 
     Assert.That(sizeChangedRaised); 

    } 

    static class ThreadEx 
    { 
     public static void Wait(int millisecondsTimeout) 
     { 
      Wait(TimeSpan.FromMilliseconds(millisecondsTimeout)); 
     } 

     public static void Wait(TimeSpan timeout) 
     { 
      var frame = new DispatcherFrame(); 
      new Thread(() => 
          { 
           Thread.Sleep(timeout); 
           frame.Continue = false; 
          }).Start(); 
      Dispatcher.PushFrame(frame); 
     } 
    } 
+0

ただ、注意すべき点は、このテストは、このフォームでは非常に安全では見えませんが、1秒のタイムアウトは非常に寛大であると私はあなたの実際のオブジェクトを操作しているかわからないけど何か他のものがサイズ変更を引き起こしている場合は、テストするものとは異なる変更のためにイベントが発生するので、ある時点でそのテストから偽陽性を得るかもしれません。 –

答えて

3

矩形がキューイングされた方法で物事を行うUIスレッドによって管理され、このテストは合格HBの静的クラスで滑り


SOLUTION

SizeChangedは、完全なメソッドが実行された後、ブレークポイントを設定するか、ブールを設定するのではなくMessageBoxを表示するだけで、実際に起動されていることがわかります。

編集:どうすればテストするのですか。ただ、事前にいくつかの遅延を追加します。

ThreadEx.Wait(1000); 
Assert.That(sizeChangedRaised); 
static class ThreadEx 
{ 
    public static void Wait(int millisecondsTimeout) 
    { 
     Wait(TimeSpan.FromMilliseconds(millisecondsTimeout)); 
    } 

    public static void Wait(TimeSpan timeout) 
    { 
     var frame = new DispatcherFrame(); 
     new Thread((ThreadStart)(() => 
     { 
      Thread.Sleep(timeout); 
      frame.Continue = false; 
     })).Start(); 
     Dispatcher.PushFrame(frame); 
    } 
} 
+0

これはDispatcherに関連していますが、私はDispatcherFrameを作成し、Dispatcher.BeginInvokeによってキューに入れられたジョブをテストできるようにDispatcher.PushFrame(フレーム)を作成しました。 ? – Grokodile

+0

@panamack:はい、これを行う1つの方法ですが、私は多分タイムアウトを介してアプローチして、イベントが発生してからテストが失敗するようにします。 –

+0

あなたは正式に私のヒーローになりました。 – Grokodile

関連する問題