Im trying to use MVC pattern in winforms but when I try invoke event it is always null. I pass GameView form to Game class to which I bind CityButtonPressed method to event but when I run it it seems like if nothing was bound.
class Game
{
private readonly IGameView _gameView;
public Game(IGameView view)
{
_gameView = view;
_gameView.CityButtonPressed = CityButtonPressed;
}
public void CityButtonPressed(object sender,EventArgs e)
{
//do something
}
}
public interface IGameView
{
event EventHandler CityButtonPressed;
}
public partial class GameView : Form,IGameView
{
public event EventHandler CityButtonPressed;
public GameView()
{
InitializeComponent();
}
protected virtual void OnButtonPressed(EventArgs e)
{
CityButtonPressed?.Invoke(this, e);
}
private void button1_Click(object sender, EventArgs e)
{
OnButtonPressed(EventArgs.Empty);
}
}
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var gameView = new GameView();
var game = new Game(gameView);
Application.Run(new GameView());
}
}
What am I doing wrong?
CodePudding user response:
Here's a cut down version of your code that shows it works.
void Main()
{
var view = new GameView();
var game = new Game(view);
view.OnButtonPressed();
}
public interface IGameView
{
event EventHandler CityButtonPressed;
}
class Game
{
private readonly IGameView _gameView;
public Game(IGameView view)
{
_gameView = view;
_gameView.CityButtonPressed = CityButtonPressed;
}
public void CityButtonPressed(object sender, EventArgs e)
{
Console.WriteLine("Pressed");
}
}
public partial class GameView : IGameView
{
public event EventHandler CityButtonPressed;
public void OnButtonPressed()
{
if (CityButtonPressed == null)
Console.WriteLine("null");
CityButtonPressed?.Invoke(this, new EventArgs());
}
}
When I run that I get Pressed
on the console. All I did is refactor your code to get it down to the minimal amount required for it to run.
It would seem you're not wiring it up correctly or your not showing us the actual minimal amount of code required.
UPDATE
You're creating two GameView
instances. There's your problem.
var gameView = new GameView();
var game = new Game(gameView);
Application.Run(new GameView());
Instead, try this:
var gameView = new GameView();
var game = new Game(gameView);
Application.Run(gameView);
CodePudding user response:
Make sure that the Game
class is instantiated with the GameView
instance before you invoke CityButtonPressed
. For example:
private Game game;
protected virtual void OnButtonPressed(EventArgs e)
{
game= new Game(this);
if (CityButtonPressed == null)
MessageBox.Show("null");
CityButtonPressed?.Invoke(this, e);
}
It is not a good solution for you because you will need the Game
instance somewhere but the CityButtonPressed
should not be null anymore.