-11

我试图通过不使用 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# 方式解决它并制作完美的平滑效果?

谢谢!

4

1 回答 1

2

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

如果我没记错的话,您的代码将快速Radius将 所有这些都将每 500 毫秒发生一次(即在每个上)。01219Tick

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

I would also like to comment on the DoEvents approach. It's most likely a bad idea. Whenever I see a DoEvents I get chills up my spine. (It reminds me of some seriously bad Visual Basic 5/6 code I stumbled across 10-15 years ago.) As I see it, an event handler should return control of the GUI thread as quickly as possible. If the operation takes a not insignificant amount of time, then you should delegate that work to a worker thread. And nowadays, you have plenty of options for writing asynchronous code.

于 2012-12-27T19:03:26.217 回答