moskalak
moskalak

Reputation: 271

Can't subscribe to an event

I'm just learning the ropes in mono and GTK# and I have encountered this problem.

I'm building a simple MVC the other way around -- from the top to the bottom (i.e. I'll build the interfaces/contracts later).

I've a Controller class:

public class ScanComparerController
{
    ScanComparerModel model;
    MainWindow view;

    public ScanComparerController ()
    {
        model = new ScanComparerModel ();
        view = new MainWindow ();

        view.Show ();

        view.Do += new MainWindow.DoHandler(PerformAction);
    }

    void PerformAction(MainWindow o, EventArgs e)
    {
        DoStuff();
    }
}

I've a view class:

public partial class MainWindow: Gtk.Window
{
    public event DoHandler Do;
    public delegate void DoHandler(MainWindow m, EventArgs e);

    public MainWindow (): base (Gtk.WindowType.Toplevel)
    {
        Build ();

        btnGo.Clicked += buttonGo_clicked;
    }

    void buttonGo_clicked(object o, EventArgs e)
    {
        CheckConditions();

        if (Do != null) 
            Do (this, EventArgs.Empty);
    }

Now, for some reason, the view always believes that Do == null, while it shouldn't, because I add a listener to it right after the initialization. Still, my code looks exactly like the one I refer to.

I know it's probably something trivial I've missed, but I can't figure it out.

EDIT 1

As suggested by undefined, I tried swapping the lines to:

view.Do += new MainWindow.DoHandler(PerformAction);
view.Show ();

Without success, however. Still, Do == null and PerformAction is never called.

EDIT 2

I tried eleting custom handler and switching to the generic EventHandler, as suggested by AdamBilinski. Still, without success.

EDIT 3

I double-checked and Do isn't referenced anywhere else in the code.

Upvotes: 0

Views: 235

Answers (2)

moskalak
moskalak

Reputation: 271

OK, I solved the problem. It was extremely trivial, sorry for bothering you.

The one class I haven't showed you was MainClass from Program.cs. It read:

class MainClass
{
    public static void Main (string[] args)
    {
        Application.Init ();
        MainWindow win = new MainWindow ();
        win.Show ();
        Application.Run ();
    }
}

Solved by changing to:

class MainClass
{
    public static void Main (string[] args)
    {
        Application.Init ();
        var controller = new ScanComparerController ();
        Application.Run ();
    }
}

The moral from this story to be drawn is: always check everything.

Upvotes: 0

undefined
undefined

Reputation: 1364

Try to swap the lines:

   view.Do += new MainWindow.DoHandler(PerformAction);

   view.Show ();

Subsribe first, then run the window cycle (view.Show ()).

Upvotes: 2

Related Questions