New to monogame seeks help taking text input for a login-screen!

Hello everyone^^ Im pretty new to programming and monogame in particular and i bet theres some obvious solution to my problem that i just havent been able to track down trough google yet. Anyway the situation:

Ive made a game with a registration, login and main menu screens. Since taking input trough monogame apparently is quiet a hassle ive tried to make winforms for my login and menu screens, which works fine, but i cant get them to communicate with my game1 monogame class.

What i need to do is change my enum GameState in Game1 to GameState.MainMenu when a button called “main menu” on the login form is clicked. Ive tried all the ways i usuallky send data between classes without luck. Anyone have experience with ssending data between form and Game1? Or have other advice? Im even willing to try take input in other ways, though it seemed very difficult to do it via monogame/xna from the guides i found.

Cheers
Kasper

Also heres my login form code:

class LoginForm
{

    public static string ShowDialog()
    {
        Form input = new Form()
        {
            Width = 800,
            Height = 600,
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None,
            StartPosition = FormStartPosition.Manual,
            Location = new System.Drawing.Point(100, 100),
            BackgroundImage = Image.FromFile(@"Content/loginBg.jpg")
        };

        bool wishedNameIsFree = true;

        TextBox textBox1 = new TextBox() { Left = 350, Top = 150, Width = 200 };
        TextBox textBox2 = new TextBox() { Left = 350, Top = 180, Width = 200 };

        Label label1 = new Label();
        label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        label1.Location = new System.Drawing.Point(210, 150);
        label1.Size = new System.Drawing.Size(120, 18);
        label1.Text = ("Wished Name: ");
        label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;

        Label label2 = new Label();
        label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
        label2.Location = new System.Drawing.Point(210, 180);
        label2.Size = new System.Drawing.Size(120, 18);
        label2.Text = ("Wished Password: ");
        label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;

        input.Controls.Add(textBox1);
        input.Controls.Add(textBox2);

        Button okCheck = new Button() { Text = "Check if OK", Left = 400, Width = 100, Top = 300, DialogResult = DialogResult.OK };

        input.Controls.Add(okCheck);
        input.Controls.Add(label1);
        input.Controls.Add(label2);
        //input.AcceptButton = okCheck;

        okCheck.Click += (sender, e) =>
        {
            // Kald databasen og tjek om det ønskede navn er i brug og -->
            if (wishedNameIsFree)
            {
                MessageBox.Show("Wished name was free, proceding to main menu!");
                input.Close();

                game1.CurrentGameState = GameState.Playing;
                // CurrentGamestate == gamestate.mainmenu
            }
            else
            {
                MessageBox.Show("Wished name is not free, try another!");
            }
        };

        string checkingWishedName = textBox1.Text;
        string checkingWishedPassword = textBox2.Text;

        return input.ShowDialog() == DialogResult.OK ? textBox1.Text : "";
        //return input.ShowDialog() == DialogResult.OK ? textBox2.Text : "";
    }

And my GameState enum in Game1:

    enum GameState
    {
        Login,      // Login, Password, OK, Register 
        Register,   // Hvis register er valgt : Wished login, Wished password, Ok, --> Gem database --> Send til MainMenu 
        MainMenu,   // Start Game, About the game, Credits, Exit Game
        About,      // Om spillet, controls, historie etc
        Credits,    // Om os udviklerne af spillet
        Playing,    // Spillogik her
        Closing,    // Gemmer alt data til databaserne så progression ikke mistes.
    }

    GameState CurrentGameState = GameState.Login;

I do not think you can achieve what you want this way. Winforms and 2D/3D rendering are different things. I may not be right, but I think you need to develop your own controls in Monogame, or use a third-party control kit, becuase in Monogame/XNA there are no such things like ‘textboxes’ and ‘radiobuttons’, At least I am not aware of any solution that does the conversion from windows forms controls to rendered controls.

At least, I am developing the required controls by myself (hell of a lot and hard work, though…), but I am not sure if this answers your question?

I have had the same issue for my game. Feel free to use the code I came up with.

`

    public class TimedKey
{

// the maximume key lifetime in seconds

    public const float MaxKeyLife = .2f;
    /// <summary>
    /// the lifetime of this key
    /// </summary>
    public float Life;

    // the key we are tracking
    public Keys Key;

    public TimedKey(Keys key)
    {
        Life = 0; //set life to zero
        Key = key;
    }
}
/// <summary>
/// A gloable keybaord API that is accesable from anywhere in the program
/// This will allow us to share the keyboard input without having to have several keyboard.getstate functions
/// </summary>
public class KeyboardAPI
{
    private static KeyboardState kb, lkb;


    private static List<TimedKey> TimedKeys = new List<TimedKey>();

    //A list of all keychars been pressed in this update sycle
    private static Queue<char> _keyBuffer = new Queue<char>();

    /// <summary>
    /// Checks to see if there is a key in the buffer
    /// </summary>
    public static bool IsKeyAvalible {  get { if (_keyBuffer.Count > 0)
                                                return true;
                                            else
                                                return false; } }

    private static Dictionary<Keys, char> _xnaKeyLookupTable = new Dictionary<Keys, char>();

    private static bool _enableCharKeyboard = false;
    public static void EnableCharKeyboard()
    {
        _enableCharKeyboard = true;
        _xnaKeyLookupTable.Add(Keys.A, 'a');
        _xnaKeyLookupTable.Add(Keys.B, 'b');
        _xnaKeyLookupTable.Add(Keys.C, 'c');
        _xnaKeyLookupTable.Add(Keys.D, 'd');
        _xnaKeyLookupTable.Add(Keys.E, 'e');
        _xnaKeyLookupTable.Add(Keys.F, 'f');
        _xnaKeyLookupTable.Add(Keys.G, 'g');
        _xnaKeyLookupTable.Add(Keys.H, 'h');
        _xnaKeyLookupTable.Add(Keys.I, 'i');
        _xnaKeyLookupTable.Add(Keys.J, 'j');
        _xnaKeyLookupTable.Add(Keys.K, 'k');
        _xnaKeyLookupTable.Add(Keys.L, 'l');
        _xnaKeyLookupTable.Add(Keys.M, 'm');
        _xnaKeyLookupTable.Add(Keys.N, 'n');
        _xnaKeyLookupTable.Add(Keys.O, 'o');
        _xnaKeyLookupTable.Add(Keys.P, 'p');
        _xnaKeyLookupTable.Add(Keys.Q, 'q');
        _xnaKeyLookupTable.Add(Keys.R, 'r');
        _xnaKeyLookupTable.Add(Keys.S, 's');
        _xnaKeyLookupTable.Add(Keys.T, 't');
        _xnaKeyLookupTable.Add(Keys.U, 'u');
        _xnaKeyLookupTable.Add(Keys.V, 'v');
        _xnaKeyLookupTable.Add(Keys.W, 'w');
        _xnaKeyLookupTable.Add(Keys.X, 'x');
        _xnaKeyLookupTable.Add(Keys.Y, 'y');
        _xnaKeyLookupTable.Add(Keys.Z, 'z');

        _xnaKeyLookupTable.Add(Keys.Space, ' ');
        _xnaKeyLookupTable.Add(Keys.OemPeriod, '.');
        _xnaKeyLookupTable.Add(Keys.OemComma, ',');
        _xnaKeyLookupTable.Add(Keys.Enter, '\n');

        _xnaKeyLookupTable.Add(Keys.Back, '#'); //the hash char will be used to denote that more needs to be done than a simple convertion
        
        _xnaKeyLookupTable.Add(Keys.End, '#'); //the hash char will be used to denote that more needs to be done than a simple convertion
        _xnaKeyLookupTable.Add(Keys.Home, '#'); //the hash char will be used to denote that more needs to be done than a simple convertion
        _xnaKeyLookupTable.Add(Keys.Escape, '#'); //the hash char will be used to denote that more needs to be done than a simple convertion

    }

    public static char ReadKey()
    {
        return _keyBuffer.Dequeue();
    }

    private static bool _supressXna = false;
    /// <summary>
    /// this fuction will disable all xna keyboard keys when run
    /// the purpues is when needing text input for a text box
    /// </summary>
    public static void DisableXnaInputThisUpdate()
    {
        _supressXna = true;
    }

    private static void XnaKeyToChar()
    {
        Keys[] ckey = kb.GetPressedKeys(); //get all current key pressed
        Keys[] okey = lkb.GetPressedKeys(); //get old keypress
        _keyBuffer.Clear(); //clear the buffer from old updates
        for (int i=0; i < ckey.Length; i++) 
            if (!okey.Contains(ckey[i])) //if a key press exist this updat but not last we have a new keypress
            {
                if (_xnaKeyLookupTable.ContainsKey(ckey[i]))
                    if (kb.IsKeyDown(Keys.LeftShift) || kb.IsKeyDown(Keys.RightShift))
                        _keyBuffer.Enqueue(Char.ToUpper(_xnaKeyLookupTable[ckey[i]]));
                else
                        _keyBuffer.Enqueue(_xnaKeyLookupTable[ckey[i]]);
            }
    }

    /// <summary>
    /// gets the keyboards states. 
    /// THIS MUST ONLY BE RUN ONCE PER UPDATE CYCLE
    /// </summary>
    public static void Update(ref float dt)
    {
        _supressXna = false;
        lkb = kb; //get last kb state
        kb = Keyboard.GetState(); //get current state of kb

        if (_enableCharKeyboard)
            XnaKeyToChar();
        
        for (int i = TimedKeys.Count - 1; i >= 0; i--) //check all timed keys
        {
            TimedKeys[i].Life += dt; //add on delta time
            if (TimedKeys[i].Life >= TimedKey.MaxKeyLife) //check if key is to old
                TimedKeys.RemoveAt(i); //remove if old
        }

    }

    /// <summary>
    /// check if the given key is drpessed
    /// </summary>
    /// <param name="key">the key to check</param>
    /// <returns></returns>
    public static bool isKeyDown(Keys key)
    {
        if (_supressXna)
            return false;
        return kb.IsKeyDown(key);
    }

    /// <summary>
    /// check if the given key is drpessed
    /// </summary>
    /// <param name="key">the key to check</param>
    /// <returns></returns>
    public static bool isKeyUp(Keys key)
    {
        if (_supressXna)
            return false;
        return kb.IsKeyUp(key);
    }

    /// <summary>
    /// Check if a key has been pressed
    /// will only return true on the initalze state change
    /// </summary>
    /// <param name="key">the key to check </param>
    /// <returns></returns>
    public static bool isKeyPressed(Keys key)
    {
        if (_supressXna)
            return false;

        if (kb.IsKeyDown(key) && lkb.IsKeyUp(key))
        {
            return true;
        }
        else
            return false;
    }

    /// <summary>
    /// Check if a key has been pressed
    /// will only return true on the initalze state change
    /// </summary>
    /// <param name="key">the key to check </param>
    /// <returns></returns>
    public static bool isKeyDoubblePressed(Keys key)
    {
        if (_supressXna)
            return false;

        if (kb.IsKeyDown(key) && lkb.IsKeyUp(key))
        {
            for (int i = 0; i < TimedKeys.Count; i++) //loop through all timed keys
                if (TimedKeys[i].Key == key) //look for if the key has alread been pressed in
                {
                    //maximume time frame
                    return true; //if it has we have a double press
                }

            TimedKeys.Add(new TimedKey(key)); //if not add the key to the timed keys
            return false;
        }
        else
            return false;
    }
}

`

call update to get keyboard inputs.
run EnableCharKeyboard() to detect keys for text input
then use ReadKey() and IsKeyAvlible to get text input.

hope it helps

Ps you will need to use DisableXnaInputThisUpdate() so the API does not read the XNA styled keyboard input
also if you get the char ‘#’ that denotes a special key where you will need to check to see if what XNA keys are pressed.