Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从控件中注销类处理程序-WPF_C#_Wpf - Fatal编程技术网

C# 从控件中注销类处理程序-WPF

C# 从控件中注销类处理程序-WPF,c#,wpf,C#,Wpf,我已经在WPF中的文本框上注册了GotFocusEvent的事件处理程序 EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus)); 现在,有没有办法从textbox中删除已注册的处理程序 更新: 我检查了以下链接 但是,它没有帮助我,因为所提到的控件是自定义控件,在我的例子中,它是默认的TextBox控件 在我的情况下

我已经在WPF中的文本框上注册了
GotFocusEvent
的事件处理程序

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
现在,有没有办法从textbox中删除已注册的处理程序

更新: 我检查了以下链接

但是,它没有帮助我,因为所提到的控件是自定义控件,在我的例子中,它是默认的
TextBox
控件


在我的情况下,我无法找到
RemoveHandler
。有什么建议吗?

如您问题的评论所述,类处理程序不能注销。我给您的建议如下:在处理程序的开头添加一个if语句,检查实际的方法体是否应该执行。这可能如下所示:

private void MyTextBoxClassHandler(对象发送方,RoutedEventTargets e)
{
如果(CheckIfHandlerShouldExecute()==false)
返回;
//应该在处理程序中执行的实际代码位于此处。
}

这不会阻止调用处理程序,但如果不满足特定条件,则不会执行逻辑。

无法注销类处理程序,但您可以在静态类中管理事件,在静态类中注册一次类处理程序,并根据需要添加/删除实例处理程序。您可以公开普通的
EventHandlers
,也可以使用反应式扩展来实现这一点:

public static class GlobalEvents
{
    static readonly ClassHandlerSubject s_TextBoxGotFocus = new ClassHandlerSubject(typeof(TextBox), UIElement.GotFocusEvent);
    public static IObservable<RoutedEventArgs> TextBoxGotFocus => s_TextBoxGotFocus.Events;

    class ClassHandlerSubject
    {
        readonly Lazy<Subject<RoutedEventArgs>> m_Subject;
        public IObservable<RoutedEventArgs> Events => m_Subject.Value;

        public ClassHandlerSubject(Type classType, RoutedEvent routedEvent) =>
            m_Subject = new Lazy<Subject<RoutedEventArgs>>(() =>
            {
                EventManager.RegisterClassHandler(classType, routedEvent, new RoutedEventHandler(OnEventReceived));
                return new Subject<RoutedEventArgs>();
            });

        private void OnEventReceived(object sender, RoutedEventArgs e) => m_Subject.Value.OnNext(e);
    }
}

RemoveHandler方法可能是实现这一点的正确方法。可能是@Nicholas的副本,我没有找到
TextBox
RemoveHandler
。有什么建议吗?您不能注销
ClassHandler
。您使用
EventManager.RegisterClassHandler
有什么具体原因吗?为什么不改用
UIElement.RegisterHandler
?正如@Novitchi正确指出的那样,您不能注销类处理程序。我已经在我对问题的评论中提到了这一点。这可能是一个解决办法,但不是答案。好吧,答案是没有API来注销注释中提到的类处理程序。避免此问题的唯一方法是不使用类处理程序,而是使用其他机制,例如通过样式在所有文本框上设置的附加属性。当提供某个值时,此附加属性将自己注册并注销到文本框中(您可以在此处了解更多信息:)。请帮自己一个忙(无意冒犯),如果(!shoulldhandlerExecute())返回,请编写
@EricG我通常不喜欢
运算符,因为我认为在阅读源代码时很容易忽略它-很难忽略a
==false
//subscribe
var subscription = GlobalEvents.TextBoxGotFocus.Subscribe(TextBox_GotFocus);
//... receive events
//remove my subscription
subscription.Dispose();