2

画面に円形のボタンがあり、それをタップしたときの効果をアニメーション化するとします。最初は、ボタン (楕円形) の背景 (塗りつぶし) は透明で、ボーダー ブラシ (アウトライン) には、ボタンのように見えるように色と太さが設定されています。

ここで、スタイラスまたはマウスが入ったときにこの楕円の背景 (塗りつぶし) をアニメーション化し、タップするとその効果が得られるようにしたいと考えています (iPhone やその他のデバイスで見たものです)。

アプリ リソースにスタイルを作成しました。

<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'' イベントをサブスクライブして、ボタンの押下を実際に処理します。ボタンを押すと、別のフォームが起動します。問題は、このフォームを起動する前にアニメーションが完了するのを待ちたいことです。このようなことは可能ですか?

4

2 に答える 2

1

Storyboard.Completed イベントを使用できます。

Duration を 00:00:01.2 に設定して、アニメーションが完了する前に実際に開かないことを確認します。

もちろん、この例ではこれを改善できます。円を離れるとポップアップが開かないことを意味すると判断しました。

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;
    }
}
于 2014-06-20T18:44:55.317 に答える
0

これは、イベント ハンドラーでフォームとアニメーションを開いているために発生しています。デフォルトでは、UI イベント ハンドラーは UI スレッド (アプリケーションの唯一のスレッド) で呼び出されるため、UI の更新と他のすべてのイベント ハンドラー タスクは同期的に実行されます。イベント ハンドラーはフォームが終了するのを待っているため、スレッドはフォームが閉じられるまで一時停止されます。このような状況を取り除くには、次のいずれかを使用できます-

  1. Event / Delegates: オブジェクト内で別のイベント ハンドラーを作成し、それをカスタム イベントにアタッチして、フォームを開き、イベント ハンドラーが呼び出されたときにそのイベントを発生させ、2 番目のイベント ハンドラーで UI を開きます。そのため、最初のイベント ハンドラーが呼び出されると、新しいスレッドでフォームを開くコードが生成され、それ自体が UI の更新を続行できます。ただし、これは以前の古いアプローチでAsync/Awaitあり、子スレッドから UI を変更する必要がある場合は、UI を更新するために追加の作業が必要になります。

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

  1. Async/Await 新製品の使用。ここにリンクがあります -

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

個人的には、効率的であり、別のスレッドから UI を更新するオーバーヘッドが発生しないため、Async/Await オプションを使用します。

于 2014-06-20T17:36:11.553 に答える