Это может ответить на ваш вопрос:
Класс не может подписаться на событие в другом классе, о котором он не знает.Класс также не может подписаться на событие, которое не существует.
Main
создает новый экземпляр ClsMain
, а затем пытается подписаться на его OnDataRetrieved
событие.
ClsMain main= new ClsMain();
main.OnDataRetrieved += OnDataRetrieved;
main.ReadData();
Console.ReadKey();
Первоначальная проблема заключается в том, что ClsMain
не имеет ни одного такого события, поэтому на него невозможно подписаться.
ClsSub
действительно имеет такое событие.Но ваше приложение не использует экземпляр ClsSub
.Он использует ClsMain
.Он не знает, что ClsMain
создает экземпляр ClsSub
, и это хорошо.Он не должен знать, что происходит внутри методов ClsMain
.Таким образом, если внутренние компоненты этого класса изменятся, ваша программа все равно будет работать.
Таким образом, чтобы ваша программа могла подписаться на событие, ClsMain
должно иметь такое событие.Как он узнает, когда нужно поднять событие?Когда он создает экземпляр ClsSub
, он может подписаться на свое событие.Когда этот класс вызывает событие, ClsMain
, в свою очередь, вызывает собственное событие.
public class ClsMain
{
public event LogHandler OnDataRetrieved;
public void ReadData()
{
ClsSub sub = new ClsSub();
sub.OnDataRetrieved += OnDataRetrieved;
sub.LoadData();
}
}
Теперь все, что ваша программа знает, это то, что ClsMain
вызывает событие.Он не знает и не заботится о том, как ClsMain
внутренне решает поднять это событие.Все это знает общедоступный интерфейс ClsMain
, а не то, как он работает внутри.Задача ClsMain
состоит в том, чтобы знать, что он создает ClsSub
, подписывается на свое событие и отвечает, вызывая собственное событие.
(Я не рассматриваю, являются ли события тем,Я бы использовал в этом сценарии - я предполагаю, что вы просто экспериментируете с событиями.)
Вот отредактированная версия кода, с которым я работал.Я просто настроил его достаточно, чтобы он скомпилировал и запустил.В коде в OP не было метода GetData
, поэтому я добавил метод, который возвращает фиктивные данные.
public class Data
{
public string ID { get; set; }
public string Description { get; set; }
}
public delegate void LogHandler(Data log);
public class ClsSub
{
public event LogHandler OnDataRetrieved;
public void LoadData()
{
DataTable dt = GetData();
foreach (DataRow row in dt.Rows)
{
Data logdata = new Data();
logdata.ID = row["UserID"].ToString();
logdata.Description = row["Description"].ToString();
if (OnDataRetrieved != null)
{
OnDataRetrieved(logdata);
}
}
}
private DataTable GetData()
{
var result = new DataTable();
result.Columns.Add("UserID", typeof(string));
result.Columns.Add("Description", typeof(string));
result.Rows.Add("user1", "description1");
result.Rows.Add("user2", "description2");
return result;
}
}
public class ClsMain
{
public event LogHandler OnDataRetrieved;
public void ReadData()
{
ClsSub sub = new ClsSub();
sub.OnDataRetrieved += OnDataRetrieved;
sub.LoadData();
}
}
public class Program
{
static void Main(string[] args)
{
ClsMain main = new ClsMain();
main.OnDataRetrieved += ClsApplication_OnDataRetrieved;
main.ReadData();
Console.ReadKey();
}
private static void ClsApplication_OnDataRetrieved(Data log)
{
Console.WriteLine(log.ID + " " + log.Description);
}
}
Вывод:
user1 description1
user2 description2