2016-09-27 2 views
1

나는 눈에 보이게하고 싶은 직사각형을 가지고있다. 그런 다음 나는 500 밀리 초를 기다리고 싶다. 그런 다음 그것을 다시 보이지 않게 만들고 싶다. 사각형의 어떤 종류를 변경하지 않고 0.5 초에 일시 정지했다 BackgroundWorker를 사용하여 WPF UI 요소를 표시하거나 숨기는 방법?

MuzzleFlash.Visibility = Visibility.Visible; 
Thread.Sleep(500); 
this.UpdateLayout(); 
this.InvalidateVisual(); 
MuzzleFlash.Visibility = Visibility.Collapsed; 

나는 그들이 가정으로 업데이트 할 창을 강제로 두 중간 선을했지만,이 모든했다 :

처음에 나는이 코드를 시도했다.

그래서 BackgroundWorkers에 대해 들었고, 어떻게 사용해야하는지 알아 보았습니다. 잠깐 읽고 나면 이걸 생각해 냈습니다. 그 촬영이 이전에 근무 캔버스에 MouseDown 이벤트,에 가입 참고 :

private void Shoot(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 

     BackgroundWorker UIUpdater = new BackgroundWorker(); 
     UIUpdater.WorkerSupportsCancellation = true; 
     UIUpdater.WorkerReportsProgress = false; 

     UIUpdater.DoWork += new DoWorkEventHandler(UI_DoWork); 
     UIUpdater.RunWorkerCompleted += new RunWorkerCompletedEventHandler(cancelUIUpdate); 

    } 

    private void UI_DoWork(object sender, DoWorkEventArgs e) 
    { 
     MuzzleFlash.Visibility = Visibility.Visible; 
     Thread.Sleep(500); 
     this.UpdateLayout(); 
     this.InvalidateVisual(); 
     MuzzleFlash.Visibility = Visibility.Collapsed; 
    } 

    private void cancelUIUpdate(object sender, RunWorkerCompletedEventArgs e) 
    { 
     BackgroundWorker bw = sender as BackgroundWorker; 
     bw.CancelAsync(); 
    } 

는 이제 심지어 노동자가 아무것도하지 않는 나에게 지시, 0.5 초 일시 정지하지 않습니다. 이 문제를 어떻게 해결하고 사각형을 표시하거나 사라지게 할 수 있습니까?

+2

타이머를 사용합니다. 너는 정말로 일을하고 있지 않다. – Paparazzi

+0

작업자 스레드에서 모든 작업을 수행하기 때문에 작동하지 않습니다. 기본 UI 스레드는 다음과 같이 말합니다. "백그라운드 작업자 시작 후 종료"* bg worker는 "시각적 플래그를 설정하고 잠시 기다렸다가 가시 플래그를 false로 설정 한 다음 UI 스레드로 다시 돌아가 UI를 업데이트 할 수 있습니다."라고 말합니다. bg 스레드는 디스플레이를 업데이트하기 위해 주 UI 스레드로 다시 알림을 보내지 않습니다. 이런 식으로하고 싶다면 WPF의 Dispatcher를 살펴 보는 것이 좋습니다. 비슷한 예제를 사용하는 간단한 요약은 [이 대답] (http://stackoverflow.com/a/15930792/302677)을 참고하십시오. – Rachel

+1

간단한 "해결책"은'MuzzleFlash.Visibility = Visibility.Visible' 라인을 메인 UI 스레드로 옮겨서'Shoot (...) '메소드 내에서 실행하는 것입니다. 그런 다음 bg worker가 ""잠시 기다렸다가 가시 플래그를 false로 설정 한 다음 다시 UI 스레드로 끝내서 업데이트 할 수 있습니다. "라고 말하면서 코드는 *"보이는 플래그를 true로 설정하고 bg 작업자를 시작한 다음 디스플레이를 끝내고 " .또한 WPF는 일반적으로 생성되지 않은 스레드의 객체를 업데이트하지 않으므로 RunWorkerCompleted에 * "visible visible flag false"* 비트를 넣을 수 있으므로 bg에서 업데이트하려고하는 예외를 얻을 수 있습니다 노동자. – Rachel

답변

4

시간 후에 값을 설정합니다. 애니메이션은 스토리 보드에서 실행해야합니다. xaml 또는 코드를 통해 지정할 수 있습니다.

직사각형을 애니메이션 귀하의 질문은 XAML 매우 간단

:

<Rectangle x:Name="MuzzleFlash" Height="100" Width="100" Fill="Red"> 
    <Rectangle.Triggers> 
     <EventTrigger RoutedEvent="Loaded"> 
      <BeginStoryboard> 
       <Storyboard> 
        <ObjectAnimationUsingKeyFrames BeginTime="0:0:0.5" Storyboard.TargetProperty="Visibility"> 
         <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" /> 
        </ObjectAnimationUsingKeyFrames> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Rectangle.Triggers> 
</Rectangle> 

더 복잡한 애니메이션의 경우, 대화 형 디자인을 혼합 사용할 수 있습니다.

의견 뒤에 업데이트 된 응답 : 표시하고 사라지려면 한 번 숨겨진 사각형으로 마우스 이벤트에 응답하지 않으면 부모 컨테이너에서 조작해야합니다.

사각형에 사각형을 넣고 이름으로 참조하여 애니메이션의 가시성을 변경할 수 있습니다.

<Grid Background="Gray"> 
    <Grid.Triggers> 
     <EventTrigger RoutedEvent="MouseDown"> 
      <BeginStoryboard> 
       <Storyboard> 
        <ObjectAnimationUsingKeyFrames BeginTime="0:0:0.0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MuzzleFlash"> 
         <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" /> 
         <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="{x:Static Visibility.Hidden}" /> 
        </ObjectAnimationUsingKeyFrames> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Grid.Triggers> 
    <Rectangle x:Name="MuzzleFlash" Height="100" Width="100" Fill="Red"> 

    </Rectangle> 
</Grid> 
+0

그러면 어떻게 시작합니까? 로드 된 그대로 말 그대로 '로드시'입니까? 아니면 코드에서 호출 할 수 있습니까? – lordnoob

+0

어떻게 작동 시키시겠습니까? 여기 예제에서는 Loaded를 예제로 사용합니다. 모든 이벤트에 대해 트리거 할 수 있습니다. 왜 코드에서 트리거 할 필요가 있다고 생각합니까? – loopedcode

+0

글쎄, 본질적으로 사각형을 클릭하여 0.5 초 동안 표시 한 다음 다시 사라지도록하고 싶습니다. MouseDown 및 Visibility to Hidden을 기본적으로 설정 했으므로 (스토리 보드에서 x : 정적 Visibility.Visible) 작동하지만 (응답 없음) 작동하지 않습니다. 이전에 MouseDown과 같은 응답을 받았지만 기본적으로 볼 수 있었기 때문에 대신 숨어있는 것 같습니다. – lordnoob

0

당신이 MVVM 당신은 다음이가 사각형에

바인딩 가시성 컨버터를 시도하고 값이 true와 false 같은 것이있을 때만 보여주고 당신의 ViewModel에 구속력이 떨어져 사용 한 경우?

다음 백그라운드 작업자에 당신은 전에 그것은 WPF에서 애니메이션을 관리하는 배경 노동자를 사용하는 좋은 생각이다

https://www.rhyous.com/2011/02/22/binding-visibility-to-a-bool-value-in-wpf/

0
private BackgroundWorker bw = new BackgroundWorker(); 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     //Background Worker code/// 
     bw.WorkerReportsProgress = true; 
     bw.DoWork += bw_DoWork; 
     bw.ProgressChanged += bw_ProgressChanged; 
     bw.RunWorkerCompleted += bw_RunWorkerCompleted; 
     bw.RunWorkerAsync(); 

     //Progress Bar Window 
     grdProgress.Visibility = Visibility.Visible; 
    } 
    private void bw_DoWork(object sender, DoWorkEventArgs e) 
    { 
     //something to do 
    } 

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     //Progress Bar Window close 
     grdProgress.Visibility = Visibility.Hidden; 
    } 

    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     prg.Value = e.ProgressPercentage; 
    } 


    bw.ReportProgress(value); 
+0

코드 제공 외에도 답변이 왜 효과가 있는지 설명하십시오. – buczek

관련 문제