自从我开始学习c#以来,我已经看到了一些处理事件的方法。假设我有一个这样的XAML按钮:
<Button x:Name="button" Content="Click me!"/>
给出这个按钮,我可以用几种方式连接一个点击事件:
修改按钮的
Click
属性以指向后面代码中的方法,如:<Button x:Name="button" Content="Click me!" Click="button_Click"/>
然后在代码中添加
button_Click
方法:private void button_Click(object sender, RoutedEventArgs e) { button.Content = "Ow >_<"; }
在后面的代码中通过委托处理事件:
button.Click += delegate { button.Content = "Ow >_<"; };
通过后面代码中的lambda表达式处理事件:
button.Click += (object sender, RoutedEventArgs e) => { button.Content = "Ow >_<"; };
给定这三个方法,我有几个问题:
- 这两种方法的根本区别是什么?
- 是否存在应该使用方法而不是方法的情况?我看到type 1主要用于WPF和WinRT应用程序,但其他两种我只在使用Xamarin时才真正看到。
- 不是WPF或WinRT所特有的,在。net的GUI设计器中,单击控件来连接默认事件或单击visual studio属性窗口中的事件是典型的。这就是大多数情况下将事件连接到控件的方式。通常使用2将事件连接起来。或3。当您在运行时创建动态控件时,事件本身并没有什么不同,但是在应用程序的生命周期中创建它们的阶段对2有很大的不同。3 . .
这些方法之间的根本区别是什么?
没有根本的区别。它们只是注册事件处理程序的不同方式。
处理事件的另一种方法(也是更易于维护的应用程序的推荐方法)实际上是将视图(GUI)与视图模型(视图背后的逻辑)分离。这被称为MVVM模式。WPF支持数据绑定,这允许您在视图模型类中定义命令,然后您可以将XAML中的按钮附加到该命令上。
查看这个stackoverflow问题了解更多信息
从内存泄漏的角度来看,您应该尽量避免方法#2和#3,除非您绝对确定这些是一次性事件订阅。理由是,你怎么退订这些?
当您编写一个简单的示例代码时,挑战是不容易看到的。但是,如果它是一个视图模型被动态地一遍又一遍地创建,基于用户双击列表(或类似的东西),并且这个VM将处理程序与另一个类的事件挂钩呢?当这些vm中的一个或多个超出范围时,如何清除事件订阅?典型的订阅删除操作如下所示:
otherClass.SomeEvent -= myHandler;
但是如果你使用匿名委托或lambda,你会怎么做呢?如果以某种方式引入两个或更多的。net认为签名相等的lambda,这将成为一场噩梦。啊。