在我的课堂上,我有一个私有的C#字典,其中键是一个字符串,值是一个有PropertyChanged
事件的对象。定义如下:
private readonly Dictionary<string, IAlsVariable> m_operatorAudibleSevServerVariables = new Dictionary<string, IAlsVariable>();
在我的构造函数中,我有以下foreach填充Dictionary
:
foreach (var clusterManager in clusterManagers)
{
var clusterName = clusterManager.Name;
string opcDataSourceServer = "server/" + clusterName + ":[2:http://www.alstom.com/Transport/Iconis/S2K/Data]<Organizes>2:S2KServer<Organizes>2:S2KTerritoryMngt<Organizes>2:TASSObject<HasComponent>2:OperatorAudibleSev";
var opcVariable = m_alsApplication.Database.GetVariable(opcDataSourceServer, null);
opcVariable.PropertyChanged += OpcVariable_PropertyChanged;
m_operatorAudibleSevServerVariables.Add(clusterManager.Name, opcVariable);
}
正如您所看到的,在我将每个变量(值)的实例添加到字典之前,我还订阅了每个变量的PropertyChanged
事件。
现在,只要其中一个变量实例触发PropertyChanged
事件,就会执行(一个)事件处理程序。问题是我不知道字典中的哪个变量触发了PropertyChanged
事件。
我有一个名为UpdateAlarmSound
的方法,每当此事件触发时我都需要调用它。我需要传递给这个方法的第一个参数是字典中相关变量的关键字。
我的第一个猜测是转换变量然后使用该值来搜索密钥。但我不知道这是否是可行的方法。下面的代码是我的。它似乎有效,但我有一些疑问,也许还有另一种更好的方法。或者也许我的方式有效,但是错了。也许我应该使用.Equals
代替==
。
private void OpcVariable_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var opcVariable = sender as IAlsVariable;
var key = m_operatorAudibleSevServerVariables.FirstOrDefault(x => x.Value == opcVariable).Key;
UpdateAlarmSound(key, Convert.ToInt32(opcVariableVtqValue));
}
答案 0 :(得分:1)
确实有效。一项改进可能是将PropertyChanged
事件信息包装在您自己的新自定义event
和新EventArgs
中,并拥有Name
和opcVariable
实例部分那件事。这样可以避免任何可能导致运行时错误的转换。
以下是EventArgs
:
public class YourEventArgs : EventArgs
{
public string Name {get;set;}
public int OpcVariableVtqValue {get;set;}
// If you still need it.
public string PropertyName {get;set;}
}
以下是IAlsVariable中所做的更改:
public interface IAlsVariable
{
event EventHandler<YourEventArgs> YourEvent;
}
现在改变实施:
public class SomeAlsVariableImpl : IAlsVariable
{
public string Name {get;}
public event EventHandler<YourEventArgs> YourEvent;
// Call this method any time you need to raise the event.
private void RaiseYourEvent(int opcVariableVtqValue)
{
YourEvent?.Invoke(this, new YourEventArgs
{
Name = Name,
OpcVariableVtqValue = opcVariableVtqValue,
}
}
}
现在,在您的主类中,您需要订阅以下事件:
foreach (var clusterManager in clusterManagers)
{
var clusterName = clusterManager.Name;
string opcDataSourceServer = "server/" + clusterName + ":[2:http://www.alstom.com/Transport/Iconis/S2K/Data]<Organizes>2:S2KServer<Organizes>2:S2KTerritoryMngt<Organizes>2:TASSObject<HasComponent>2:OperatorAudibleSev";
var opcVariable = m_alsApplication.Database.GetVariable(opcDataSourceServer, null);
opcVariable.YourEvent += OpcVariable_YourEvent;
m_operatorAudibleSevServerVariables.Add(clusterManager.Name, opcVariable);
}
然后:
private void OpcVariable_YourEvent(object sender, YourEventArgs e)
{
UpdateAlarmSound(e.Name, e.OpcVariableVtqValue));
}
当您的主要课程被处理以避免内存泄漏时,请不要忘记取消订阅该事件。