2

我从另一篇文章中找到了这种语法(C#如何停止动画 gif 不断循环),但似乎我无法理解。s和e的含义或目的是什么

System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));


// start
System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));

// stop
System.Drawing.ImageAnimator.StopAnimate(txImage.Image, (s, e) => OnFrameChanged(s, e));

private void OnFrameChanged(object sender, EventArgs e)
{
// frame change
}

或者任何人都可以简单地解释一下。抱歉我很愚蠢,但我对编程真的很陌生,但我真的很想学习谢谢

4

2 回答 2

1

您可以通过三种基本方式编写事件处理程序。不幸的是,该代码的作者通过不恰当地混合它们而弄错了。他应该使用的是原始的C#版本1方式:

ImageAnimator.Animate(txImage.Image, OnFrameChanged);

这是非常直接且易于理解的。当然,在这种情况下您应该非常喜欢的语法,它使得调用 StopAnimate() 方法变得非常容易。要回答您的问题,我需要展示其他两种方式,即您不应该使用的方式。在 C# 版本 2 中,可以使用匿名委托就地编写事件处理程序的代码:

ImageAnimator.Animate(txImage.Image, delegate {
    // Put the OnFrameChanged code here...
});

在 C# 版本 3 中,可以使用 lambda 表达式就地编写事件处理程序:

ImageAnimator.Animate(txImage.Image, (s, e) => {
    // Put the OnFrameChanged code here...
});

这是你问的。lambda 表达式的 (s, e) 部分表示传递给事件处理程序的两个参数,s 是发送者,e 是 EventArgs 对象。请注意,您实际上并没有在 OnFrameChange 代码中使用这两个参数,因此 lambda 语法是多余的,匿名委托也可以正常工作。尽管许多 C# 程序员已经停止使用它们,而是更喜欢在任何地方使用 lambda 表达式语法。这是公平的。即使您不使用参数,您仍然必须编写它们以使编译器相信您的 l​​ambda 是委托的适当替代品。就像您仍然必须使用两个参数编写 OnFrameChanged 以使编译器满意一样。

理解 lambda 表达式语法可能会有点困难,任何关于 C# 语言的体面的介绍性书籍都会比我解释它做得更好。

最后但并非最不重要的一点是,您将在此答案中找到一些hackorama 代码,以向您展示如何在完全不必使用 ImageAnimator 类的情况下暂停 PictureBox 中的动画。尽管有一些可能性,这只会增加更多问题:)

于 2013-07-14T11:26:54.003 回答
0

Animate 和 StopAnimate 期望“一个 eventHandler 对象,该对象指定动画帧更改时调用的方法”。您可以将其解读为

System.Drawing.ImageAnimator.Animate(txImage.Image, new EventHandler(this.OnFrameChanged))
于 2013-07-14T04:07:25.553 回答