WinForm Новый экземпляр формы - PullRequest
1 голос
/ 13 декабря 2011

У меня есть этот блок кода:

Form1 newForm = new Form1();
newForm.Show(); 

//The rest of this code has been omitted

больше или меньше. Form1 только для примера. Моя проблема в том, что я создаю текстовый редактор (в основном продолжение моего последнего вопроса), и я хочу иметь возможность открывать более одной копии формы Form1 одновременно.

Этот код позволяет мне сделать это, и это здорово, но я хочу иметь возможность закрыть старый и все еще иметь новую форму на экране. В настоящее время, если я закрываю Form1, я прощаюсь с newForm.

Возможно ли это? Я не хочу просто отключать все последующее, как Блокнот.

Ответы [ 4 ]

4 голосов
/ 13 декабря 2011

Я предполагаю, что ваш Form1 также создан и передан Application.Run() в вашем main методе, верно? Что-то вроде Application.Run(new Form1());

В этом случае (который используется по умолчанию) вы указываете платформе выйти из приложения, когда эта форма закрывается.

Возможно, вы захотите изменить метод main на использование перегрузки Application.Run(), которая принимает ApplicationContext , и в контексте приложения создайте свои формы - затем, когда закроется последняя форма, вы можете выйти из приложения. Пример в ссылке на MSDN показывает очень похожий случай.

Вы можете просто изменить main на:

Form1 newForm = new Form1();
newForm.Show();
Application.Run();

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

Добавлено: Это простой пример, но показывает концепцию. Создайте класс ApplicationContext, как этот:

public class CustomContext : ApplicationContext
{
    private readonly List<Form1> _openForms = new List<Form1>();

    public CustomContext()
    {
        CreateForm();
    }

    private void CreateForm()
    {
        Form1 form = new Form1();
        form.OpenNewForm += (sender, args) =>  CreateForm();
        form.Closed += (sender, args) => FormClosed(sender as Form1);
        _openForms.Add(form);
        form.Show();
    }

    private void FormClosed(Form1 form)
    {
        _openForms.Remove(form);
        if (_openForms.Count == 0)
        {
            ExitThread();
        }
    }
}

В вашем Program классе измените main на Run(..) ваш новый контекстный класс:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new CustomContext());
}

А затем в вашей Form1 убедитесь, что у вас есть событие, и инициируйте это событие, чтобы открыть новые формы (обратите внимание, что в «реальном» коде я бы, вероятно, абстрагировал это, или, скорее всего, мой контейнер DI обрабатывал регистрацию, но это показывает гораздо более ясный смысл):

public event EventHandler OpenNewForm;
private void ButtonClick(object sender, EventArgs e)
{
    //instead of showing a new form, we just raise this event
    if (OpenNewForm != null) OpenNewForm(this, EventArgs.Empty);
}

Это позволяет приложению ApplicationContext управлять открытыми формами, так что закрытие первой (или любой из них) не приводит к выходу из приложения, пока вы не закроете последнюю . Как только последняя форма закрывается, она выходит из приложения.

1 голос
/ 13 декабря 2011

Вы можете сделать это так по-разному.Для рабочего примера того, что вы хотите сделать, в файле Program.cs измените метод Main ():

static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());
            Form1 frm = new Form1();
            GlobalVariables.FormsList = new List<Form1>();  //new
            GlobalVariables.FormsList.Add(frm);             //new
            frm.Show();
            Application.Run();
        }

Затем на каждой из ваших форм Form1 есть кнопка (или другое событие), которая создает экземплярновый экземпляр формы1:

private void button1_Click(object sender, EventArgs e)
        {
            Form1 frm = new Form1();
            GlobalVariables.FormsList.Add(frm);     //new
            frm.Show();
        }

Редактировать: также добавить следующий код в событие FormClosing:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (GlobalVariables.FormsList.Count == 1)
    {
        Application.Exit();
    }
    else
    {
        GlobalVariables.FormsList.RemoveAt(GlobalVariables.FormsList.Count - 1);
    }
}

Редактировать: вот новый класс GlobalVariables со списком форм дляуправление формой помощи:

   public class GlobalVariables
    {
       public static List<Form1> FormsList { get; set; }
    }
0 голосов
/ 13 декабря 2011

В зависимости от того, что именно вы хотите сделать, форма может быть запущена с помощью Application.Run, которая будет просто запускать другие формы (например, форму вашего текстового редактора).

Что-то вроде: (Это просто пример для демонстрации идеи.)

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        Shown += Form1_Shown;
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        TextEditorForm frm2 = new TextEditorForm(this);
        frm2.Show();
        this.Hide();
    }
}

И

public partial class TextEditorForm : Form
{
    Form1 frm1;

    public TextEditorForm(Form1 frm1)
    {
        InitializeComponent();
        this.frm1 = frm1;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        frm1.Show();
        this.Close();
    }
}
0 голосов
/ 13 декабря 2011

Если вы закрываете форму с помощью кнопки «х», это не повлияет на другую форму. Если вы закрываете по коду, вы должны правильно получить объект этой формы и закрыть его. Было бы лучше, если бы вы могли вести каталог форм, чтобы управление было легким.

Если между ними есть какие-либо статические переменные, попробуйте изменить эту логику без статических переменных, поскольку они совместно используются объектами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...