【发布时间】:2019-04-27 19:19:28
【问题描述】:
您好,我从https://www.youtube.com/watch?v=jQgwEsJISy0&t=1230s 了解到事件和委托。在这他说要使事件发生,我们需要三个步骤
- 定义委托
- 根据该委托定义事件
- 引发该事件
我跟随他并在控制台中制作了应用程序,但由于我在 WPF 中工作,我将在此处发布我在 WPF 中使用的代码,代码如下:
namespace WpfApp5
{
public delegate void step1DelegateDefinition(); // Step-1: Define a delegate
public interface INotifyOnVideoEncoded
{
event step1DelegateDefinition EventDefinedInInterface;// Step-2a: Define an event based on that delegate
}
public partial class MainWindow : Window, INotifyOnVideoEncoded
{
public event step1DelegateDefinition EventDefinedInInterface; //Step-2b: Define an event based on that delegate
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
ObservableCollection<string> NotificationText = new ObservableCollection<string>();
EventDefinedInInterface += SubscriberMethodForConection;// A method corresponding to delegate is subscribed for that event
Encode();
}
public void Encode()
{
MessageBox.Show("Encoding Video...");
Thread.Sleep(3000);
PublisherMethodForConnection(); //Step-3: Raise an event
}
public void PublisherMethodForConnection()
{
if (EventDefinedInInterface != null)
EventDefinedInInterface();
else
MessageBox.Show("No Subscriber");
}
public void SubscriberMethodForConection()
{
MessageBox.Show("MailService: Sending an email...");
}
}
}
所以我的知识是这样的
必须订阅事件才能使用 += 符号执行。
但与我的知识相比,当我使用 INotifyPropertyChange 中的 propertychange 事件时,不需要 += 符号。而且奇怪的是似乎+ =(订阅事件)是动态完成的,但是因为如果我首先初始化属性(在我的情况下,如果我初始化FirstName = Jeff和LastName = Buckley的值,则在下面的代码中显示)然后它会触发我的代码中的 else 部分在开头显示消息“没有 MyOnPropertyChanged 函数可以调用的订阅者”。我相信这是因为事件订阅者是空的(即没有像我期望的那样 += 事件分配语句)但是稍后一旦加载窗口,似乎有事件订阅者虽然我没有在代码上这样做。下面是我的代码实现属性更改。
namespace UnderstandingINotifyPropertyChanged
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _FirstName;
private string _FullName;
private string _LastName;
public string FirstName
{
get { return _FirstName; }
set
{
if (_FirstName != value)
{
_FirstName = value;
MyOnPropertyChanged_PublisherMethod("FirstName");
MyOnPropertyChanged_PublisherMethod("FullName");
}
}
}
public string LastName
{
get { return _LastName; }
set
{
if (_LastName != value)
{
_LastName = value;
MyOnPropertyChanged_PublisherMethod("Lastname");
MyOnPropertyChanged_PublisherMethod("FullName");
}
}
}
public string FullName
{
get { return _FullName = _FirstName + " " + _LastName; }
}
private void MyOnPropertyChanged_PublisherMethod(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
else
MessageBox.Show("There is no Subscriber to which MyOnPropertyChanged function can call ");
}
public MainWindow()
{
InitializeComponent();
FirstName = "Jeff";
LastName = "Buckley";
this.DataContext = this;
}
}
}
所以我的困惑是在第一个代码中我必须使用 += 分配事件,但在第二个代码中它可以在不执行 += 的情况下工作。我无法弄清楚第二个代码如何在不使用 += 的情况下运行,因为需要使用 += 将事件链接到订阅者。
我尝试在线阅读并查看视频以进行解释,但不明白这是我在这里问的原因。到目前为止,我已经从这里学到了很多东西,谢谢你,也感谢你花时间阅读这个问题,我可以在你的帮助下掌握这一点。
【问题讨论】:
-
您正在实现接口,这意味着您通常只通过
MyOnPropertyChanged_PublisherMethod(这是一个奇怪的名称)触发事件。订阅它的是事件的消费者。例如一个绑定。 -
触发事件的方法通常称为 NotifyPropertyChanged 或 RaisePropertyChanged,并且应该只有一行:
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); -
@Clemens 感谢您的回复,我很困惑的是,如果 MyOnPropertyChanged_PublisherMethod 是与事件 PropertyChanged 相关联的函数,那么我们不必按顺序执行 PropertyChanged+= MyOnPropertyChanged_PublisherMethod 之类的操作调用它,或者因为我在我的属性的设置器中调用它,所以在这种情况下我不必做 += 。我很困惑,因为我们在另一个示例中使用 += 将方法链接到事件而不是此处(EventDefinedInInterface += SubscriberMethodForConection),而不是在这个示例中。
-
不,我们没有。如前所述,您不订阅生产者端的事件。您只能通过
PropertyChanged?.Invoke触发它。 -
@Clemens 我已经根据您关于名称和使用的建议更改了我的代码?运算符而不是 If else。同时,我还想问是否可以更改我的代码(第二个代码)以使用 += 而不是在属性设置器中调用事件绑定函数,前提是我想要相同的函数。如果您有任何来源,那就太好了,再次感谢您的回复:D
标签: c# wpf events delegates inotifypropertychanged