VB.NET中的EventHandler管理

时间:2009-08-19 09:08:04

标签: vb.net events event-handling

您好我现在正在使用VB.NET的项目中,需要将这个C#代码翻译成VB.NET

oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;

newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;

对我来说,这似乎是一个事件与另一个事件挂钩? 但我已经尝试了一切将其转换为VB.NET代码? 我发现VB.NET中的EventHandler管理远不如C#和其他很多东西一样好。

那我怎么能在VB.NET中做到这一点?

编辑:这里是我要翻译的代码,所有代码都很容易翻译,但是OnCommandChanged方法中的代码。

public class CommandReference : Freezable, ICommand
{
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command",
        typeof(ICommand),
        typeof(CommandReference),
        new PropertyMetadata(new PropertyChangedCallback(OnCommandChanged)));

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (Command != null)
            return Command.CanExecute(parameter);
        return false;
    }

    public void Execute(object parameter)
    {
        Command.Execute(parameter);
    }

    public event EventHandler CanExecuteChanged;

    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CommandReference commandReference = d as CommandReference;
        ICommand oldCommand = e.OldValue as ICommand;
        ICommand newCommand = e.NewValue as ICommand;

        if (oldCommand != null)
        {
            oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged;
        }
        if (newCommand != null)
        {
            newCommand.CanExecuteChanged += commandReference.CanExecuteChanged;
        }
    }

    #endregion

    #region Freezable

    protected override Freezable CreateInstanceCore()
    {
        throw new NotImplementedException();
    }

    #endregion
}

3 个答案:

答案 0 :(得分:2)

“远远不如”?它同样好,语义也不同:)

尝试

RemoveHandler okButton.Click, addressof OkButton_ClickHandler

AddHandler okButton.Click, addressof OkButton_ClickHandler

更新

嗨,我错过了你的问题的意图,道歉。

我对你的方法感到困惑,当你在两个事件之间放置+ =​​和 - =时,你没有挂钩并解开事件,你只是添加和删除存在于处理器中的处理程序那一刻。即你没有将事件a挂钩到事件b,你正在挂钩当前已分配给a的处理程序。因此,如果(例如)在分配之后所有处理程序都从b 中删除,它们仍将被分配给

我可能遗漏了一些显而易见的遗憾,我现在也没有时间深入了解如何在WPF中实现依赖属性,这是我接下来会看到的。

抱歉,我无法提供更多帮助。

答案 1 :(得分:0)

我认为您正在寻找内置函数AddHandlerRemoveHandler。不像C#那样明确,但很有用。

还在VB Programming Guide

中介绍

答案 2 :(得分:0)

当我在实现特殊INotifyCollectionChanged时,当我需要知道实例是否附加了事件处理程序时,我遇到了类似的问题。

经过一些搜索后,我从ObservableCollecion(Of T)中取出了一页以便进行此操作。

您尝试转换为VB的代码是:

public event EventHandler CanExecuteChanged; 

private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    CommandReference commandReference = d as CommandReference; 
    ICommand oldCommand = e.OldValue as ICommand; 
    ICommand newCommand = e.NewValue as ICommand; 

    if (oldCommand != null) 
    { 
        oldCommand.CanExecuteChanged -= commandReference.CanExecuteChanged; 
    } 
    if (newCommand != null) 
    { 
        newCommand.CanExecuteChanged += commandReference.CanExecuteChanged; 
    } 
} 

你需要更多代码,但它是这样的:

Private __CanExecuteCommand as EventHandler

Public Custom Event CanExecuteChanged As EventHandler 
    AddHandler(ByVal value As EventHandler)
        Dim handler2 As EventHandler
        Dim canExecuteCommand = __CanExecuteCommand
        Do
            handler2 = canExecuteCommand
            Dim handler3 = DirectCast(System.Delegate.Combine(handler2, value), EventHandler)
            canExecuteCommand = Interlocked.CompareExchange((__CanExecuteCommand), handler3, handler2)
        Loop While (Not canExecuteCommand Is handler2)
        __CanExecuteCommand = canExecuteCommand
    End AddHandler
    RemoveHandler(ByVal value As EventHandler)
        Dim handler2 As EventHandler
        Dim canExecuteCommand = __CanExecuteCommand
        Do
            handler2 = canExecuteCommand
            Dim handler3 = DirectCast(System.Delegate.Remove(handler2, value), EventHandler)
            canExecuteCommand = Interlocked.CompareExchange((__CanExecuteCommand), handler3, handler2)
        Loop While (Not canExecuteCommand Is handler2)
        __CanExecuteCommand = CanExecuteCommand
    End RemoveHandler
    RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
        If (__CanExecuteCommand IsNot Nothing) Then
            __CanExecuteCommand.Invoke(sender, e)
        End If
    End RaiseEvent
End Event

Private Shared Sub OnCommandChanged(d as DependencyObject, e as DependencyPropertyChangedEventArgs) 

    Dim commandReference = CType(d, CommandReference) 
    Dim oldCommand = CType(e.OldValue, ICommand) 
    Dim newCommand = CType(e.NewValue, ICommand)

    If (oldCommand IsNot Nothing) Then
        RemoveHandler oldCommand.CanExecuteChanged, commandReference.__CanExecuteChanged; 
    End If
    If (newCommand IsNot Nothing)  Then
        AddHandler newCommand.CanExecuteChanged, commandReference.__CanExecuteChanged; 
    End If

End Sub 

所以现在你不仅可以检查事件是否有处理程序,还可以移动它们。