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:在对象内部创建另一个事件处理程序并将其附加到自定义事件,只是为了打开表单,然后在调用事件处理程序时触发该事件并在第二个事件处理程序中打开 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

我个人会选择 Async/Await 选项,因为它很高效,而且不会给您从单独的线程更新 UI 的开销。

于 2014-06-20T17:36:11.553 回答