Search code examples
c#winformscustom-events

How to correctly reset a custom event in C#?


I have this code:

private void loadGENIOFileToolStripMenuItem_Click(object sender, EventArgs e)
{
    OpenFileDialog dlgFile = new OpenFileDialog();

    dlgFile.InitialDirectory = Properties.Settings.Default.PreviousPath;
    dlgFile.Title = "Select GENIO file";
    dlgFile.Filter = "GENIO files (*.txt)|*.txt";
    dlgFile.FilterIndex = 0;
    dlgFile.Multiselect = false;

    if (dlgFile.ShowDialog() == DialogResult.OK)
    {
        Properties.Settings.Default.PreviousPath = Path.GetDirectoryName(dlgFile.FileName);

        DeleteView();

        m_oThreadServices.OnLoadingCompleted += (_sender, _e) =>
        {
            mruMenu.AddFile(dlgFile.FileName);
            m_sUITInfo.dbDatabase = m_oThreadServices.GetDatabase();
            CreateView();
        };

        m_oThreadServices.SetGenioFilePath(dlgFile.FileName);
        m_oThreadServices.start();
    }
}

But I am also trying to implement a MRU handler:

    private void OnMruFile(int number, String filename)
    {
        if (File.Exists(filename))
        {
            Properties.Settings.Default.PreviousPath = Path.GetDirectoryName(filename);

            DeleteView();

            m_oThreadServices.OnLoadingCompleted += (_sender, _e) =>
            {
                mruMenu.SetFirstFile(number);
                m_sUITInfo.dbDatabase = m_oThreadServices.GetDatabase();
                CreateView();
            };

            m_oThreadServices.SetGenioFilePath(filename);
            m_oThreadServices.start();
        }
        else
            mruMenu.RemoveFile(number);
    }
}

My m_oThreadServices.OnLoadingCompleted line of code seems to require that I use += and as a result, if I first load a file, it adds the first event handler. If I then go to use the MRU list to load a different file it ends up running two OnLoadingCompleted handlers.

I tried m_oThreadServices.OnLoadingCompleted = but it will not allow it. So what is the right way for me to intercept the event handler and not end up calling both sets of code? Am I going about it wrong?

Thank you.


Solution

  • You should make sure your event handlers are unsubscribed from the event source once the event is raised.

    In order to do that, you have to modify a bit the anonymous handlers. For instance, this snippet:

    m_oThreadServices.OnLoadingCompleted += (_sender, _e) =>
    {
        mruMenu.AddFile(dlgFile.FileName);
        m_sUITInfo.dbDatabase = m_oThreadServices.GetDatabase();
        CreateView();
    };
    

    should be like this:

    EventHandler onLoadingCompleted = null;
    onLoadingCompleted = (_sender, _e) =>
    {
        m_oThreadServices.OnLoadingCompleted -= onLoadingCompleted;
        mruMenu.AddFile(dlgFile.FileName);
        m_sUITInfo.dbDatabase = m_oThreadServices.GetDatabase();
        CreateView();
    };
    m_oThreadServices.OnLoadingCompleted += onLoadingCompleted;
    

    Same for the other.

    The line

    EventHandler onLoadingCompleted = null;
    

    is needed to avoid using uninitialized variable compiler error here

    m_oThreadServices.OnLoadingCompleted -= onLoadingCompleted;