2016-10-09 3 views
0

WindowsFormsHost 컨트롤의 내용을 캡쳐 한 스크린 샷을 Grid 컨트롤의 배경에 적용하는 WPF 응용 프로그램이 있습니다. Grid는 WindowsFormsHost에서 다른 WPF 컨트롤로의 전환 화면 역할을합니다. 이것은 부드러운 전환 효과를 만들고 공기 공간 문제를 피하기 위해 수행됩니다. 우선 WinFormsHost 컨트롤 이미지를 비트 맵으로 캡처하여 그리드 배경에 적용합니다. 그런 다음 전환 격자의 가시성을 프로그래밍 방식으로 시각적으로 변경합니다. 그런 다음 불투명도 애니메이션을 사용하여 다른 컨트롤을 부드럽게 표시합니다. 그것은 응용 프로그램을 테스트하는 컴퓨터에 따라 완벽하게 70-90 %의 시간 동안 작동합니다. 문제는 전환 격자 배경이 충분히 빠르거나 정확한 시간에 렌더링되지 않는다는 것입니다. 따라서 때때로 전이 시간에 현재 화면 이미지와 일치하지 않는 이전 전환에서 스크린 샷을보고 있습니다.WPF 컨트롤의 배경을 설정하고 표시시 즉시 렌더링을 보장하는 방법?

그리드가 표시되기 전에 어떻게 든 전환 이미지가 그려 지도록 할 수 있다면 매번 작동 할 것입니다. 나는 이것을 어떻게하는지 알 수 없다. 응용 프로그램은 렌더링을 수행 할 마지막 순간까지 항상 기다리는 것처럼 보입니다.

Dispatcher.Invoke() 및 Dispatcher.BeginInvoke() 메서드를 사용하여 렌더링을 강제 실행하려고 시도했습니다. Grid가 Dispatcher Timer로 표시되는 시간을 지연 시키려고했지만, 호출이 백그라운드 이미지를 설정하고 가시성을 설정하는 사이에 아무리 많은 시간이 있더라도 Grid는 항상 업데이트되지는 않습니다. 나는 또한 운이없는 InvalidateVisual() 같은 것을 시도했다.

는 WPF의 갈라진 및 UI 스레드와 관련된 문제로 많은 예제를보고 후, 나는이 문제를 해결하기위한 여러 가지 시도를 ...

시도 1 - 제대로 작동하지만 시도는 그 첫 번째 코드의 라인과 함께 잘 작동 배경을 아무 것도 또는 검은 색으로 설정합니다.

   TransitionScreen.Visibility = Visibility.Visible 
       TransitionScreen.Background = Nothing 
       TransitionScreen.Background = New ImageBrush(BitmapToImageSource(GrabScreenshot(ScreenWidth, ScreenHeight))) 

       State = "WPFControlMode" 
       SwitchState() 

시도 2 ​​- 지금까지의 최상의 결과. 컴퓨터에 따라 공정하게 잘 작동합니다. 카운터 값을 높이더라도 결과는 향상되지 않습니다. ,

Case "Transition" 
      'Grab Screen Shot and apply to transition screen...' 

      TransitionScreen.Visibility = Visibility.Visible 
      TransitionScreen.Background = Nothing 
      TransitionScreen.Background = New ImageBrush(BitmapToImageSource(GrabScreenshot(ScreenWidth, ScreenHeight))) 


End Select 


'The following code is inside a loop...' 
If State = "Transition" Then 
TransitionCounter += 1 

     If TransitionCounter = 25 Then 
      TransitionCounter = 0 

      TransitionScreen.Visibility = Visibility.Visible 
      TransitionScreen.Background = Nothing 
      TransitionScreen.Background = New ImageBrush(BitmapToImageSource(GrabScreenshot(ScreenWidth, ScreenHeight))) 

      State = "WPFControlMode" 
      SwitchState()   

     End If 

End If 

시도 3, 4, 5 : TransitionScreen의 모양은 더 큰 카운터 값 지연 될 것이지만, 이전 화면 (내 노트북에 약 1 5 회)를 표시하는 동일한 기회를 가질 것 ... - Dispatcher를 통해 작업하여 제어 렌더링을 강제로 시도합니다. 이러한 시도는 도움이되지 않는 것으로 나타나 종종 문제를 악화시킵니다. 그들은 시도 1과 2와 함께 사용되었습니다.

Case "Transition" 
      'Grab Screen Shot and apply to transition screen...' 

      TransitionScreen.Visibility = Visibility.Visible 
      TransitionScreen.Background = Nothing 
      TransitionScreen.Background = New ImageBrush(BitmapToImageSource(GrabScreenshot(ScreenWidth, ScreenHeight))) 

      FlushWindowsMessageQueue() 


End Select 

'Tried many variations of the following procedure. Every dispatcher priority with both BeginInvoke and Invoke methods, as well as calling the methods through Application and TransitionScreen objects.' 

Private Sub FlushWindowsMessageQueue() 
    Application.Current.Dispatcher.Invoke(_ 
    New Action(AddressOf DummySub), _ 
    DispatcherPriority.Background, _ 
    New Object() {}) 
End Sub 

Private Sub DummySub() 
End Sub 

더 많은 시도가 있었지만, 이것은 내가 시도한 것에 대한 아이디어를 제공합니다. 이것은 진짜 수수께끼입니다. 이것은 상당히 복잡한 프로젝트의 마지막 주요 문제점이며, 나는이 시점에서 전환 스크린에 꽤 투자하고있다. 당신이 무엇이든을 생각할 수있는 경우에, 나는 그것을 중대하게 평가할 것이다. 감사.

답변

0

이 문제에 대한 해결 방법을 생각해 냈습니다. 스크린 샷을 찍기 전에 전환 애니메이션을 사용합니다. 전환 애니메이션을 사용하면 일반적으로 컨트롤이 표시하는 것보다 낮은 해상도의 이미지가 생성됩니다. 그런 다음 전환 격자 컨트롤에 적용 할 수있는 저해상도 이미지의 스크린 샷을 찍습니다.이 이미지는 눈에 보이게 된 후 빠르게 깜박 거리지 않습니다. 그런 다음 WinFormsHost 컨트롤로 돌아가고 싶을 때이 프로세스를 역으로 실행합니다. 내 응용 프로그램은 현재 플리커없이 작동하고 내가 시도한 대부분의 컴퓨터에서 부드럽게 실행됩니다. 대형 모니터가있는 일부 컴퓨터에서는 때때로 화면 전환을 렌더링 할 때 약간의 지연이 있지만 깜박임은 없습니다. 지연은 약 0.5 초이며, 전환 이미지를 렌더링해야하는 더 큰 영역과 관련 있다고 가정합니다.

또한 위의 방법/시도 # 2와 함께 수행되었습니다. 플리커는 시도 # 1과 결합하여 여전히 발생합니다.

관련 문제