Как открыть форму new. С#

Проблема: Я решил сделать интерфейс. Сбоку которого есть кнопочки. При нажатии на кнопочку исполняется код, который переключает на дочернею форму. При переходе на другую дочернею форму по нажатию кнопочки загружается форма, и если хочешь вернутся на прошлую дочернею форму, то эта форма загружается заново. Повышается потребление ОЗУ и пропадают ведённые данные. Вот кусок кода:

 public void openChildForm(Form childForm, object btnSender)
        {
            if (activeForm != null)
                activeForm.Hide();
            activeForm = childForm;
            childForm.TopLevel = false;
            childForm.FormBorderStyle = FormBorderStyle.None;
            childForm.Dock = DockStyle.Fill;
            panelChildForm.Controls.Add(childForm);
            panelChildForm.Tag = childForm;
            childForm.BringToFront();
            childForm.Show();
        }

 private void btnSettings_Click(object sender, EventArgs e)
        {

            openChildForm(new Settings(), sender);
        }

Использовал hide и show, толку нет.


Ответы (1 шт):

Автор решения: aepot

Так как сложно разобраться с тем, что вы натворили в коде, приведу отдельный пример, как один из способов реализовать окно настроек.

  • В главном окне Form1 одна кнопка с именем button1 и названием Settings, заданным в дизайнере
  • Дочернее окно Form2 будет вызываться как модальное, то есть будет блокировать доступ к основному окну, пока оно открыто
  • Form2 содержит 3 контрола textBox1, и 2 кнопки button1 OK, и button2 Cancel

Суть примера в том, что название главного окна можно поменять в окне настроек, сохранить или отменить сохранение настроек. При закрытии программы настроки сохраняются в XML файл settings.xml в каталоге с программой. При запуске программы соответственно оттуда загружаются, и если файла нет (например при первом запуске программы), то устанавливаются по умолчанию.

Класс настроек Settings.cs

[Serializable]
public class Settings
{
    // здесь и задам значение по умолчанию
    public string WindowName { get; set; } = "My Application";
}

Далее, реализую окно настроек, при этом событие Form.Load в дизайнере привяжу к обработчику Form2_Load.

Далее на button1 я назначаю в дизайнере DialogResult.OK, на button2 - DialogResult.Cancel

Form2.cs

public partial class Form2 : Form
{
    // публично доступное свойство с настройками
    public Settings Settings { get; set; }

    // никогда не вставляйте свой код в конструктор формы
    public Form2()
    {
        InitializeComponent();
    }

    // гружу настройки в TextBox здесь
    private void Form2_Load(object sender, EventArgs e)
    {
        textBox1.Text = Settings.WindowName;
    }

    // А здесь записываю значение TextBox в настроки
    private void button1_Click(object sender, EventArgs e)
    {
        Settings.WindowName = textBox1.Text;
    }
}

Далее, главное окно Form1. События Form.Load и Form.FormClosing привязываю с обработчикам Form1_Load и Form1_FormClosing соовтетственно.

Form1.cs

public partial class Form1 : Form
{
    // путь к файлу с настройками
    private readonly string _settingsFilePath = Path.Combine(Application.StartupPath, "settings.xml");

    // сами настройки, которые я буду хранить в классе главного окна
    private Settings _settings;

    public Form1()
    {
        InitializeComponent();
    }

    // этот обработчик вызывается при запуске приложения
    private void Form1_Load(object sender, EventArgs e)
    {
        LoadSettings();
        ApplySettings();
    }

    // этот обработчик вызывается при закрытии приложения
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        SaveSettings();
    }

    // загрузить настройки их XML файла
    private void LoadSettings()
    {
        // если файл есть
        if (File.Exists(_settingsFilePath))
        {
            // гружу из него настройки
            XmlSerializer serializer = new XmlSerializer(typeof(Settings));
            using (StreamReader sr = new StreamReader(_settingsFilePath)) 
            {
                _settings = serializer.Deserialize(sr) as Settings;
            }
        }
        else
        {
             // если файла нет, просто создаю новые
            _settings = new Settings();
        }
    }

    // сохранить настройки в XML файл
    private void SaveSettings()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Settings));
        using (StreamWriter sw = new StreamWriter(_settingsFilePath))
        {
            serializer.Serialize(sw, _settings);
        }
    }

    // применить настройки к окну
    private void ApplySettings()
    {
        Text = _settings.WindowName;
    }

    // кнопка Settings открывает окно настроек
    private void button1_Click(object sender, EventArgs e)
    {
        Form2 formSettings = new Form2 { Settings = _settings };
        if (formSettings.ShowDialog(this) == DialogResult.OK)
        {
            _settings = formSettings.Settings;
            ApplySettings();
        }
    }
}

Главный прикол состоит в том, что XmlSerializer сам превращает класс в XML файл (сериализует), и обратно (десереализует) автоматически.

Создайте этот пример у себя на базе нового Windows Forms приложения и потестируйте его. Окно настроек конечно создается заново каждый раз, но при закрытии оно корректно уничтожается (назначение DialogResult кнопке автоматически закрывает модальное окно, вызванное с помощью ShowDialog()). Хранить в памяти только необходимые данные - дешевле и проще, чем целое окно.

К тому же ShowDialog() - это удобно. Например дочернему окну можно задать в дизайнере свойство StartPosition значение CenterParent, и оно появится ровно по центру родительского окна.

Пробуйте, тестируйте.

→ Ссылка