【问题标题】:Making smooth effect in WPF manually in C# with DispatcherTimer使用 DispatcherTimer 在 C# 中手动在 WPF 中制作平滑效果
【发布时间】:2012-12-12 02:31:00
【问题描述】:

我正在尝试通过不使用 Storyboard 或 WPF 中其他准备好的/已经完成的东西来产生相当的效果。

我想制作平滑的效果,在某些事件(如点击)上,UI 元素会调整 2-3 秒的大小并随着颜色的变化而模糊。我想以流畅漂亮的方式制作所有这些物品。

我已经准备了这样的类来渲染我的效果的每一帧:

public static class ApplicationHelper
{
        [SecurityPermissionAttribute(SecurityAction.Demand,
        Flags=SecurityPermissionFlag.UnmanagedCode)]
        public static void DoEvents(DispatcherPriority priority)
        {
            DispatcherFrame frame = new DispatcherFrame();
            DispatcherOperation oper = Dispatcher.CurrentDispatcher.
                            BeginInvoke(priority,
                            new DispatcherOperationCallback(ExitFrameOperation),
                            frame);

            Dispatcher.PushFrame(frame);
            if (oper.Status != DispatcherOperationStatus.Completed)
            {
                oper.Abort();
            }
        }

        private static object ExitFrameOperation(object obj)
        {
            ((DispatcherFrame)obj).Continue = false;
            return null;
        }

        [SecurityPermissionAttribute(SecurityAction.Demand,
        Flags=SecurityPermissionFlag.UnmanagedCode)]
        public static void DoEvents()
        {
            DoEvents(DispatcherPriority.Background);
        }
}

这里我试图让它与 DispatcherTimer 一起工作:

   void vb1_click(object sender, System.Windows.Input.MouseButtonEventArgs e)
   {
       DispatcherTimer dt = new DispatcherTimer();
       dt.Interval = new TimeSpan(0, 0, 0, 0, 500);
       dt.Tick += new System.EventHandler(dt_Tick);
       dt.Start();
   }

   void dt_Tick(object sender, System.EventArgs e)
   {
       for(int i = 0; i < 20; i++)
       {
           this.vb2_blur_eff.Radius = (double)i;
           ApplicationHelper.DoEvents();     
       }
   }

主要问题是,当我启动它时,我只是在等待,并且在最后时间(必须渲染最后一帧的时间),我在所有帧中都以非常快的速度获得,但以前在那里什么都不是。

如何在不使用一些现成/完成的东西的情况下,以纯 C# 方式解决它并制作完美的平滑效果?

谢谢!

【问题讨论】:

  • @punker76 它并没有重新发明它正在实施
  • 好的,但是为什么不使用可视状态管理器的可视状态呢?
  • @punker76 视觉状态和状态管理器使用什么?他们不使用 DispatcherTimer 并以类似的风格工作吗?

标签: wpf silverlight effects dispatcher smooth


【解决方案1】:

dt_Tick 中的 ApplicationHelper.DoEvents() 可能什么都不做,因为没有要处理的事件。至少不是你可能期待的。

如果我没记错的话,您的代码会快速将Radius 设置为0,然后是12,以此类推,最后是19。所有这些将每 500 毫秒发生一次(即在每个 Tick 上)。

我想你可能认为每个Tick 只会将Radius 设置为一个值,然后等待下一个Tick,但事实并非如此。每个Tick 都会将Radius 设置为所有值,以19 结尾。这是您所经历的一种可能的解释。

我还想对DoEvents 方法发表评论。这很可能是个坏主意。每当我看到DoEvents 时,我都会脊背发凉。 (它让我想起了我在 10 到 15 年前偶然发现的一些非常糟糕的 Visual Basic 5/6 代码。)在我看来,事件处理程序应该尽快返回对 GUI 线程的控制。如果该操作花费了大量时间,那么您应该将该工作委托给工作线程。现在,你有很多选择来编写异步代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多