2011-07-27 2 views
2

설명서에 따르면 "(FrameworkElement.SizeChanged) ActualHeight 또는 ActualWidth 속성이이 요소의 값을 변경하면 발생합니다."이 코드에서 FrameworkElement.SizeChanged가 발생하지 않는 이유

다음 테스트 메서드를 실행하면 Measureangle 및 Arrange를 호출 한 후 내 Rectangle의 ActualWidth 및 ActualHeight가 업데이트되지만 SizeChanged RoutedEvent는 절대로 발생하지 않습니다.

[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가 발생하지 않는지 설명 할 수 있습니까?
제기 할 수 있도록 설정할 수있는 방법이 있습니까? HB의 정적 클래스에서이 테스트를 미끄러


솔루션

패스 : 사각형은 대기 방식으로 일을 수행하는 UI 스레드에 의해 관리되는

[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

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와 관련이 있습니다. Dispatcher.BeginInvoke에 대기중인 작업을 테스트 할 수 있도록 DispatcherFrame을 만들고 Dispatcher.PushFrame (프레임)을 호출 한 다른 테스트가 있습니다. RoutedEvents를 가져 오기 위해 유사한 인프라가 필요합니다. ? – Grokodile

+0

@panamack : 예, 그 일을하는 한 방법이 될 것입니다. 아마 그 시간까지 이벤트가 발생하지 않으면 테스트가 실패하기 때문에 시간 초과를 통해 접근 할 것입니다. –

+0

이제 공식적으로 내 영웅이되었습니다. – Grokodile

관련 문제