ssd
ssd

Reputation: 2422

Dynamic creation of forms & containers

I'm very new to C#.

Below is a code that I'm trying to create forms and containers within the code; but I've problems with it.

  1. I start with a new Windows Forms Application template.
  2. I change the Program.cs file a little, so that I'd be able to create the FormMain dynamically.
  3. When the lines Container.Add(BtnClose) and BtnClose_Setup() in FormMain.cs are commented, the code compile and run. However, there are still some weird results in the program.

(a) The form FormMain is supposed to show up at (20, 20) (upper left corner), as the FormMain_Setup says; but when I run the app, though width & height settings show up as expected (800, 600), the upper left corner changes every time (does not stick to 20, 20).

(b) The esc key works as expected and closes the form and application.

  1. When the lines Container.Add(BtnClose) and BtnClose_Setup() in FormMain.cs are not commented, the code compile but VS sends me a message when it's run: "An unhandled exception of type 'System.TypeInitializationException' occurred in mscorlib.dll"

Can someone tell me what I'm doing wrong?

Program.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace test {
    static class Program {
        public static FormMain FormMain = new FormMain();
        [STAThread]
        static void Main() {
            Application.Run(FormMain);
        }
    }
}

FormMain.cs file:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace test {
    public partial class FormMain : Form {
        Button BtnClose = new Button();
        public void BtnClose_Setup() {
            BtnClose.Text = "Ok";
            BtnClose.Top = 500;
            BtnClose.Left = 700;
        }
        public void FormMain_Setup() {
            Top = 20;
            Left = 20;
            Width = 800;
            Height = 600;
            KeyDown += FormMain_KeyDown;
            //Container.Add(BtnClose);
            //BtnClose_Setup();
        }
        void FormMain_KeyDown(object sender, KeyEventArgs e) {
            if(e.KeyCode == Keys.Escape) {
                Close();
            }
        }
        public FormMain() {
            InitializeComponent();
            FormMain_Setup();
        }
    }
}

Upvotes: 1

Views: 284

Answers (2)

Andrew Radford
Andrew Radford

Reputation: 3337

By default a forms StartPosition is set to WindowsDefaultLocation. You need to set it to Manual; either in the designer or in the code.

To add a control to a form, you want to add it to the form's Controls collection, not the Container.

Also, if you want the form to continue to get KeyDown events after the button is added you need to set KeyPreview to true.

public void FormMain_Setup()
{
    StartPosition = FormStartPosition.Manual;
    KeyPreview = true;
    Top = 20;
    Left = 20;
    Width = 800;
    Height = 600;
    KeyDown += FormMain_KeyDown;
    Controls.Add(BtnClose);
    BtnClose_Setup();
}

Upvotes: 1

whyleee
whyleee

Reputation: 4049

Call Controls.Add(BtnClose); instead of Container.Add(BtnClose);.

As for fixing the form position: set StartPosition = FormStartPosition.Manual; property.

To properly close the form on Esc, override ProcessCmdKey method:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.Escape)
    {
        Close();
        return true;
    }

    return base.ProcessCmdKey(ref msg, keyData);
}

Upvotes: 2

Related Questions