从C#转换后保留使用委托引发事件的方法很困难

时间:2012-08-23 20:01:28

标签: c# vb.net events delegates callback

所以在最后一两天我一直在研究this article,以便了解依赖属性和路由命令,并希望利用一些示例代码来解决另一个项目中的内容扩展问题。该项目恰好用vb.net编写,此示例代码在C#中。

好的,没问题。我见过的大多数教程和演示项目都使用C#,我发现阅读代码并在vb.net中编写它的等价物是一种非常好的方法来理解实际发生的事情并且使用它们更加舒适。这很耗时,但在我的经验水平上是值得的(#00FF00)

不久之后我遇到了回调方法事件的问题。考虑这种方法:

public static class AnimationHelper
{

...

public static void StartAnimation(UIElement animatableElement,
                                  DependencyProperty dependencyProperty,
                                  double toValue,
                                  double animationDurationSeconds,
                                  EventHandler completedEvent)
{
    double fromValue = (double)animatableElement.GetValue(dependencyProperty);

    DoubleAnimation animation = new DoubleAnimation();
    animation.From = fromValue;
    animation.To = toValue;
    animation.Duration = TimeSpan.FromSeconds(animationDurationSeconds);

    animation.Completed += delegate(object sender, EventArgs e)
    {
        //
        // When the animation has completed bake final value of the animation
        // into the property.
        //
        animatableElement.SetValue(dependencyProperty, animatableElement.GetValue(dependencyProperty));
        CancelAnimation(animatableElement, dependencyProperty);

        if (completedEvent != null)
        {
            completedEvent(sender, e);
        }
    };

    animation.Freeze();

    animatableElement.BeginAnimation(dependencyProperty, animation);
}

将此方法转录到vb.net很简单,除了正确处理DoubleAnimation的Completed事件和回调方法的方法。我最好的尝试看起来像:

Public NotInheritable Class AnimationHelper

...

Public Shared Sub StartAnimation(...)

...

animation.Completed += Function(sender As Object, e As EventArgs)

            animatableElement.SetValue(dependencyProperty, animatableElement.GetValue(dependencyProperty))
            CancelAnimation(animatableElement, dependencyProperty)
            RaiseEvent completedEvent(sender, e)
        End Function
...

End Sub

这导致两个抱怨:

  1. 'completedEvent'不是[namespace]的事件.AnimationHelper

  2. '公共事件已完成(...)'是一个事件,无法直接调用。使用RaiseEvent ...

  3. (1)对我来说有点神秘,因为completedEvent(As EventHandler)是方法声明中的参数之一。从行首删除RaiseEvent并像普通方法一样调用它似乎满足了visual studio,但我不知道它是否会在运行时工作或者它是否有效。在(2)中语法看起来很可疑,将RaiseEvent添加到行首会导致类似于(1)的类似抱怨。

    我将继续搜索堆栈以及更大的互联网,以便在vb.net中对代表和事件进行良好的引导,因为显然我已经停止了解它们是如何工作的。与此同时,欢迎提出意见/建议。

2 个答案:

答案 0 :(得分:0)

  1. 为什么要尝试提升该事件处理程序? EventHandler只是一个代表。只需在C#中执行它:

    if completedEvent IsNot Nothing then
        completedEvent(sender, e)
    end if
    

答案 1 :(得分:0)

我认为这里的主要问题是你没有用AddHandler以VB方式添加处理程序。如果您将代码重写为:

Dim handler As EventHandler = Sub(sender, e)
    x.SetValue(dependencyProperty, x.GetValue(dependencyProperty))
    CancelAnimation(x, dependencyProperty)
    ' See note below...
    RaiseEvent completedEvent(sender, e)
End Sub

AddHandler animation.Completed, handler

......我相信它会奏效。目前尚不清楚RaiseEvent部分是否仍然会导致问题,但至少订阅animation.Completed应该没问题。如果RaiseEvent部分导致问题,请根据Daniel的回答直接调用委托。

请注意在此处使用Sub而非Function,因为代理人不会返回任何内容。