2014-06-20 5 views
2

화면에 둥근 버튼을 두드려서 애니메이션 효과를주고 싶다고 가정 해 보겠습니다. 처음에는 버튼 (타원) 배경 (채우기)이 투명하고 테두리 브러시 (윤곽선)는 버튼처럼 보일 수 있도록 약간의 색상과 두께가 있습니다.WPF 이벤트를 처리하기 전에 애니메이션 대기 종료

필자는이 타원의 타원을 스타일러스 또는 마우스로 입력하면이 타원의 효과를 줄 수 있습니다 (아이폰 및 다른 장치에서 본 것처럼). 다음

<Style x:Key="circularButton" TargetType="Ellipse"> 
    <Style.Triggers> 
     <EventTrigger RoutedEvent="StylusEnter"> 
      <BeginStoryboard> 
       <Storyboard FillBehavior="Stop"> 
        <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="Transparent" To="#993C5E66" Duration="00:00:00.2" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
     <EventTrigger RoutedEvent="StylusLeave"> 
      <BeginStoryboard> 
       <Storyboard> 
        <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="#993C5E66" To="Transparent" Duration="00:00:00.2" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
     <EventTrigger RoutedEvent="MouseEnter"> 
      <BeginStoryboard> 
       <Storyboard> 
        <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="Transparent" To="#993C5E66" Duration="00:00:00.2" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
     <EventTrigger RoutedEvent="MouseLeave"> 
      <BeginStoryboard> 
       <Storyboard> 
        <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="#993C5E66" To="Transparent" Duration="00:00:00.2" /> 
       </Storyboard> 
      </BeginStoryboard>     
     </EventTrigger> 
    </Style.Triggers> 
</Style> 

그리고 ''StylusDown ''/ ''MouseDown ''이벤트가 실제로 버튼을 눌러을 처리하기 위해 가입 :

나는 응용 프로그램 자원 스타일을 만들었습니다. 버튼을 누르면 다른 양식이 시작됩니다. 문제는이 양식을 시작하기 전에 애니메이션이 완료 될 때까지 기다려야한다는 것입니다. 이게 가능한가?

+0

방금 ​​이벤트 처리기에서 잠을 넣어 시도 했습니까? WPF에서는 폼이 아닙니다. 그리고 휴가 중에 취소하고 싶을 수도 있습니다. – Paparazzi

+0

이벤트 취소 중 (예 : e.Handled = true) 정말 필요합니까? – Crypton

답변

0

이벤트 핸들러에서 양식과 애니메이션을 열 때 발생합니다. 기본적으로 UI 이벤트 핸들러는 UI 스레드 (응용 프로그램의 유일한 스레드)에서 호출되므로 UI ​​업데이트와 기타 모든 이벤트 처리기 작업이 동 기적으로 수행됩니다. 이벤트 처리기는 양식이 완료 될 때까지 기다리고 있으므로 양식이 닫힐 때까지 스레드가 일시 중지됩니다. 이러한 상황을 제거하려면, 당신은 할 수 중 하나를 사용 -

  1. Event/Delegates : 다른 이벤트 핸들러를 생성하고 사용자 정의 이벤트에 첨부, 바로 이벤트 핸들러에 불이 이벤트를 호출 할 때 다음 양식을 열고하는 객체의 내부 두 번째 이벤트 처리기에서 UI를 엽니 다. 따라서 첫 번째 이벤트 핸들러가 호출되면 새 스레드에서 폼 열기 코드가 생성되고 UI 자체를 계속 업데이트 할 수 있습니다. 그러나 이것은 이전의 접근 방법 인 Async/Await 이전이며 UI에서 자식 스레드와 관련된 내용을 변경해야 할 경우 UI를 업데이트하는 데 추가 작업이 필요합니다.

http://msdn.microsoft.com/en-us/library/5z57dxz2(v=vs.90).aspx

  1. 를 사용하여 새로운 freatues의 Async/Await.

    http://msdn.microsoft.com/en-us/library/hh191443.aspx

개인적으로 나는 그것의 효율적인 이후, 비동기/기다리고 있습니다 옵션에 갈 것이며, 또한 당신에게 별도의 스레드에서 UI를 업데이트하는 오버 헤드를 제공하지 않습니다 - 여기에 대한 링크입니다. 애니메이션이 끝날 때까지 실제로 열리지 않는 있는지 01.2 : 00 :

00의 시간을 넣어 :

+0

나는 그것을 깨닫는다, 그러나 이것이 정확하게 문제인지 나는 확신하지 못한다. 나는 폼이 그 일을 끝내기를 기다리지 않고있다. 기본적으로 탭 애니메이션이 일어나기를 원한다. 그런 다음 폼을 열어 보자. 그러나, 단추/타원에 대한 스타일 참조를 통해 느슨하게 결합 된 애니메이션 지시문이 들어있는 스토리 보드를 참조하는 것처럼 보이지는 않습니다. – Crypton

1

당신은 Storyboard.Completed 이벤트를 사용할 수 있습니다.

이 예제에서는 물론이 부분을 개선 할 수 있습니다. 즉, 원형을 벗어나면 팝업이 열리지 않는다는 의미입니다.

XAML :

<Window> 
     <Window.Resources> 

     <Storyboard FillBehavior="Stop" x:Key="StylusEnterSB" Completed="Storyboard_Completed"> 
      <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="Red" To="#993C5E66" Duration="00:00:00.2" /> 
     </Storyboard> 

     <Storyboard x:Key="StylusLeaveSB" Completed="Storyboard_Completed"> 
      <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="#993C5E66" To="Transparent" Duration="00:00:00.2" /> 
     </Storyboard> 

     <Storyboard x:Key="MouseEnterSB" Completed="Storyboard_Completed"> 
      <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="Red" To="#993C5E66" Duration="00:00:00.2" /> 
     </Storyboard> 

     <Storyboard x:Key="MouseLeaveSB" Completed="Storyboard_Completed"> 
      <ColorAnimation Storyboard.TargetProperty="(Ellipse.Fill).Color" From="#993C5E66" To="Red" Duration="00:00:00.2" /> 
     </Storyboard> 

     <Style x:Key="circularButton" TargetType="Ellipse"> 
      <Style.Triggers> 
       <EventTrigger RoutedEvent="StylusEnter"> 
        <BeginStoryboard Storyboard="{StaticResource StylusEnterSB}" />      
       </EventTrigger> 
       <EventTrigger RoutedEvent="StylusLeave"> 
        <BeginStoryboard Storyboard="{StaticResource StylusLeaveSB}" />      
       </EventTrigger> 
       <EventTrigger RoutedEvent="MouseEnter" > 
        <BeginStoryboard Storyboard="{StaticResource MouseEnterSB}" />       
       </EventTrigger> 
       <EventTrigger RoutedEvent="MouseLeave"> 
        <BeginStoryboard Storyboard="{StaticResource MouseLeaveSB}" />     
       </EventTrigger> 
      </Style.Triggers> 
     </Style>  
</Window.Resources> 

<Grid>  
    <Ellipse Style="{StaticResource circularButton}" Width="25" Height="25" Fill="Red" MouseLeftButtonUp="Ellipse_MouseLeftButtonUp" MouseLeave="Ellipse_MouseLeave" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" MouseEnter="Ellipse_MouseEnter"  />  
</Grid> 

CS :

public partial class MainWindow : Window 
{ 
    Popup w = new Popup(); 
    public MainWindow() 
    { 
     InitializeComponent(); 

     w.Height = 200; 
     w.Width = 200; 
     w.Child = new Rectangle() { Fill = Brushes.Red, Stretch = Stretch.Fill }; 
     w.Placement = PlacementMode.Right; 
     w.PlacementTarget = this; 
    } 

    bool canPress = false;  
    private void Storyboard_Completed(object sender, EventArgs e) 
    { 
     canPress = true; 

     if(isMouseDown) 
     { 
      w.IsOpen = true; 
      isMouseDown = false; 
     } 
    } 


    bool isMouseDown = false; 
    private void Ellipse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
    { 
     if (isMouseDown && canPress) 
     { 
      w.IsOpen = true; 
      isMouseDown = false; 
     } 

    } 

    private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     isMouseDown = true; 
    } 

    private void Ellipse_MouseEnter(object sender, MouseEventArgs e) 
    { 
     isMouseDown = false; 
     canPress = false; 
       _currentEllipse = (Ellipse)sender; 
    } 

    private void Ellipse_MouseLeave(object sender, MouseEventArgs e) 
    { 
     w.IsOpen = false;  
        _currentEllipse = null; 
    } 
} 
+0

특정 타원에서 스토리 보드에 대한 참조를 가져 오는 방법이 있습니까? 차라리 글로벌 스토리 보드 완료 이벤트를 처리하지 않고 특정 타원과 스토리 보드에 연결합니다. – Crypton

+0

나는 당신이 지정한 것을 할 수 없었다. 타원이 보낸 사람이면 전역 이벤트 핸들러를 체크인 할 수 있습니다. –

+0

감사합니다. 조금 더 설명하고 내 결과를 게시 할 수 있는지 알아 보겠습니다. – Crypton