简体   繁体   中英

Listening for a custom event fired from different winform

I am working on a librarian application (in Visual Studio 2013, C#) which allows employers to loan, return and reserve books for customers. There is a small problem with creating, firing and listening for custom events.

There is one form which adds data to a so-called Reservartion table, in my database. It adds a record with current date, itemID and other data.

When the adding of this done, I want to fire a custom event, which will be listened to from a different form. When this event is fired, I need the total data in the Reservation Table to be shown when the event is fired.

I use an onclick method in my main form, which opens a new form where data will be entered and afterwards, as described above, added into database. When the data has been added, the form closes and the main form receives focus again.

The only problem now is, when all this is done, I need the entire data in the Reservartion Table to be shown onscreen (it needs to refresh itself). Which is where I need an event to be raised.

How do I create a custom event in one form, which will be listen for INSIDE an onclick method?

I included some of the code for reference.

This is the code from the main form buttonclick:

private void btnToevoegR_Click(object sender, EventArgs e)
{
    Forms.HandAddReserveer HAR = new Forms.HandAddReserveer();
    HAR.Show();
    // listen for event raised
    // When event is raised do this

    DataTable DT = DBReserveer.getAllReserveerItems();
    gvUitleen.DataSource = DT;

}

And in the other form, where the event should be raised

private void button1_Click(object sender, EventArgs e)
{
    int pasID;
        int itemID;

        if (int.TryParse(tbItemID.Text, out itemID))
        {
            if (int.TryParse(tbPasID.Text, out pasID))
            {
                if ((DBReserveer.ReserveerPasCheck(itemID, pasID)) != 0)
                {
                    MessageBox.Show("Je hebt dit item al gereserveerd!");
                }
                if ((DBReserveer.ReserveerPasCheck(itemID, pasID)) == 0)
                {
                    if (MessageBox.Show("Weet je zeker dat je dit item wilt reserveren?", "Reserveren?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        DBReserveer.ReserveerItem(itemID, pasID);
                        if (DBReserveer.QueryStatus == true)
                        {
                            MessageBox.Show("Het item is gereserveerd!");
                            // Event should be raised from here
                        }
                    }
                }
            }
        }

}

You could subscribe to the FormClosed Event of HAR.

private void btnToevoegR_Click(object sender, EventArgs e)
{
     Forms.HandAddReserveer HAR = new Forms.HandAddReserveer();
     HAR.FormClosed += new FormClosedEventHandler(HAR_FormClosed);
     HAR.Show();
}

private void Har_FormClosed(Object sender, FormClosedEventArgs e) {
     DataTable DT = DBReserveer.getAllReserveerItems();
     gvUitleen.DataSource = DT;
}

Another way would be to create your on event, like this in the form, that is being closed:

public event EventHandler<EventArgs> ReservationComplete;

protected virtual void OnReservationComplete()
{
    EventHandler<EventArgs> handler = this.ReservationComplete;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}

Raise the event, by adding a call to OnReservationComplete()

  if (DBReserveer.QueryStatus)
  {
     MessageBox.Show("Het item is gereserveerd!");
     this.OnReservationComplete();
      // Event should be raised from here
  }

and listen to the event like this (I'm not sure if the += syntax is correct. I'm writing the code from the top of my head. Feel free to correct):

private void btnToevoegR_Click(object sender, EventArgs e)
{
     Forms.HandAddReserveer HAR = new Forms.HandAddReserveer();
     HAR.ReservationComplete += Har_ReservationComplete;
     HAR.Show();
}

private void Har_ReservationComplete(Object sender, EventArgs e) {
     DataTable DT = DBReserveer.getAllReserveerItems();
     gvUitleen.DataSource = DT;
}

Edit: Third option. You could display the 2nd form as modal.

private void btnToevoegR_Click(object sender, EventArgs e)
{
     Forms.HandAddReserveer HAR = new Forms.HandAddReserveer();
     HAR.ShowDialog();
     DataTable DT = DBReserveer.getAllReserveerItems();
     gvUitleen.DataSource = DT;
}

You could do it with an event. But why so cumbersome? Why not simply refreshing the list when reservation succeeded. You're already in the correct method for that anyway.

Edit Like this:

...        
if (MessageBox.Show("Je hebt dit item al gereserveerd!") == DialogResult.OK)
{
    <Refresh list>
}    
...

Edit 2
Seems like I misinterpreted the question a bit. If the list-to-refresh resides in the other form then you would give the second form a reference to it on opening.

In the second form, you would declare a property that takes a reference to Form 1:

public partial class Form2
{
    public Form1 CallingForm { get; set; }
    ...

... set this reference upon opening Form2 ...

private void btnToevoegR_Click(object sender, EventArgs e)
{
    Forms.HandAddReserveer HAR = new Forms.HandAddReserveer();
    HAR.CallingForm = this;
    ...

... finally the second Form will call the Refresh operation on Form1 on closing:

if (MessageBox.Show("Je hebt dit item al gereserveerd!") == DialogResult.OK)
{
    CallingForm.<Refresh list>
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM