上课通知'需要改变的另一个类(事件?)

时间:2014-08-19 13:15:33

标签: c# .net

好的,我一直在搜索网站和谷歌,并且无法完全了解代表和事件处理程序等方面需要做的事情,所以希望有人可以帮助/解释我需要什么做。

所以,我正在编写一个简单的数据库应用程序(使用SQLite)。有一个主要形式是MDI父级(这基本上是一个大窗口,顶部有菜单)。菜单启动其他窗口,允许查看,编辑和插入数据库的各个表。

其中一个窗口是一个LOG窗口,显示我的日志表。

目前,如果用户在窗口中更改显示TABLE中数据的内容。该操作还会写​​入日志表。但是,如果“日志”窗口处于打开状态,则日志视图不会更新。

所以,我发现我可能需要从我的LOG窗口“订阅”的TABLE UPDATE代码中“触发”一个事件(因此它可以更新DataGridView)。

我无法弄清楚事件的不同“位”在哪里。

MdiParent是否应该有public delegate void EventHandler();?如果不在哪里?

哪个班级获得public static event EventHandler logGoneStale;

我唯一可以肯定的是,显示日志的窗口(其中有一个名为public void UpdateLogDataGridView()的方法 - 调用数据库对象/方法来(重新)填充datagridview)需要有:

其中有logGoneStale += new EventHandler(UpdateLogDataGridView);之类的东西。这至少是对的吗?

完全被迷惑 - 似乎MSDN上没有任何事件示例/教程试图做我想要实现的目标。

2 个答案:

答案 0 :(得分:0)

您需要在发送事件的类中定义event,并在应该接收事件的类中附加事件处理程序。为了使事情稍微简单一些,从C#3.5开始,您可以完全忘记delegate关键字并使用lamba表达式作为事件处理程序。另请注意,在大多数情况下,创建事件static是没有意义的,因为通常事件是由实例触发的,而不是由触发的。 / p>

示例:

class SendsEvent
{
    public event EventHandler MyEvent;

    public void FireEvent()
    {
        if(MyEvent != null) // MyEvent is null if no handlers have been attached
        {
            MyEvent(this, new EventArgs()); // event fired here
        }
    }
}

class ReceivesEvent
{
    private SendsEvent eventSource;

    public ReceivesEvent(SendsEvent eventSource)
    {
        this.eventSource = eventSource;

        // Attach event handler - can be a lambda expression
        // or method with signature 
        // "void HandleEvent(object sender, EventArgs e)"
        this.eventSource.MyEvent += (sender, args) =>
        {
            // do something when event was fired
            Console.Out.WriteLine("Hello. Event was fired.");
        };
    }
}

class Program
{
    public static void Main()
    {
        var eventSource = new SendsEvent();
        var eventReceiver = new ReceivesEvent(eventSource);
        eventSource.FireEvent(); 
    }
}

我希望这会对你有所帮助。

答案 1 :(得分:0)

使用活动要求您同时拥有活动发布者和活动订阅者。

@chris'回答是正确的。

此外,您需要在最接近您希望收到通知的操作的位置处举起活动。

例如,实现INotifyPropertyChanged接口。

public class Customer : INotifyPropertyChanged {
    public string Name { get; set; }
    public string Address {
        get { return address; }
        set {
            address = value;
            if (thereArePropertyChangedEventSubcribers()) 
                raisePropertyChangedEventFor("Address");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void raisePropertyChangedEventFor(string propertyName) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private bool thereArePropertyChangedEventSubcribers() { 
        return PropertyChanged != null; 
    }

    private string address;
}

所以在这里,Customer类允许发布其地址变更。因此,每当有人有兴趣在地址发生变化时收到通知时,它就会订阅这样的事件:

Customer.PropertyChanged += new PropertyChangedEventHandler(customerPropertyChanged);

或者像这样:

Customer.PropertyChanged += customerPropertyChanged;

您甚至可能已经注意到地址在实际更改后直接更改的最近点。唯一的要求是用作事件处理程序的方法与事件本身具有相同的签名。如果您查看PropertyChangedEventHandler Delegate,可能会注意到它的签名等待object作为第一个参数,即触发事件的对象,以及PropertyChangedEventArgs实例通知有关已更改的财产。

回到您的示例,您希望每当将日志插入基础数据库时都会注意到,以便可以刷新日志窗口。每当您想要使用事件时,都需要回答两个问题。

  • 我的出版商应该是什么?
  • 我的订阅者应该是什么?

我的出版商应该是什么?

  

MdiParent是否应该有public delegate void EventHandler();

简答:不!

  

如果不在哪里?

事件声明最适合发布商。如果你有一个负责记录的类,那么这就是public delegate void EventHandler();应该驻留的地方,因为只要有订阅者就负责提升事件。

只要插入了成功的日志,它就会通知任何有兴趣了解新日志条目的用户。

public class Log {
    public void UpdateLog(string description) {
        // insert the new Log line into your database.
        if (thereIsAtLeastOneNewLogEntryAddedSubscriber())
            raiseTheNewLogEntryAddedEvent();
    }

    public event EventHandler NewLogEntryAdded;

    private raiseTheNewLogEntryAddedEvent() {
        NewLogEntryAdded(this, EventArgs.Empty);
    }

    private bool thereIsAtLeastOneNewLogEntryAddedSubscriber() {
        return NewLogEntryAdded != null;
    }
}

我的订阅者应该是什么?

这个问题可以通过另一个问题来回答:

  • 事件发生时你需要做什么?

在您的情况下,您希望在打开日志窗口时更新。

  

我唯一可以肯定的是,显示日志的窗口(其中有一个名为public void UpdateLogDataGridView()的方法 - 调用数据库对象/方法(重新)填充datagridview)需要:

     

其中包含logGoneStale += new EventHandler(UpdateLogDataGridView);之类的内容。这至少是对的吗?

是的,你是对的! = d

您实际上是按此行订阅了该活动。因此,它告诉应用程序显示日志的窗口有兴趣了解数据库中的日志更改。

public class WindowThatDisplaysTheLog : Form {
    public WindowThatDisplaysTheLog() { 
        InitializeComponent(); 
        log = new Log();
        log.NewLogEntryAdded += UpdateLogDataGridView;
    }

    private void UpdateLogDataGridView(object sender, EventArgs e) {
        // Reload your Log entries from the underlying database.
        // You now shall see the LogDataGridView updating itself 
        // whenever a new log entry is inserted.
    }

    private Log log;
}