Как я могу создать единую форму (а не приложение)?

В моем приложении С# у меня есть диалоговое окно параметров, которое можно открыть из команды меню.

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

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

Может ли кто-нибудь указать мне, как выполнить эти задачи?

Большое спасибо.

Ответ 1

Вам понадобится эта форма как свойство

Form1 myForm = null;
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    myForm = null;
}

private void ShowForm()
{
    if (myForm != null)
    {
        myForm.BringToFront();
    }
    else
    {
        myForm = new Form1;
        myForm.Show();
    }
}

Ответ 2

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

Обратите внимание, что это не то же самое, что сделать его одиночным - потому что я предполагаю, что если форма закрыта, вам нужно будет создать новый экземпляр в следующий раз. (Альтернатива - скрытие и повторное использование - отображается в ответе STO.) Вы можете захотеть что-то вроде этого:

public class OptionsDialog : Form
{
    private static OptionsDialog openForm = null;

    // No need for locking - you'll be doing all this on the UI thread...
    public static OptionsDialog GetInstance() 
    {
        if (openForm == null)
        {
            openForm = new OptionsDialog();
            openForm.FormClosed += delegate { openForm = null; };
        }
        return openForm;
    }
}

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

Ответ 3

Вам нужно предотвратить закрытие формы. Если вы этого не сделаете, форма будет удалена и станет непригодной для использования. Вы можете сделать это, выполнив событие FormClosing:

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (e.CloseReason == CloseReason.UserClosing) {
            this.Hide();
            e.Cancel = true;
        }
    }

Чтобы сделать его одиночным, просто отслеживайте время жизни формы в своем классе основной формы:

    frmOptions options;

    private void btnShowOptions_Click(object sender, EventArgs e) {
        if (options == null) {
            options = new frmOptions();
            // To make absolutely sure:
            options.FormClosed += (o, ea) => options = null;
        }
        else {
            options.WindowState = FormWindowState.Normal;
        }
        options.Show();
    }

Ответ 4

вы можете использовать такой код:

private MyDialogForm _FormInstance;

public void ShowOptions()
{
     if (_FormInstance == null)
     {
        _FormInstance = new MyDialogForm();
        _FormInstance.FormClosing += (s,e) => 
        {
             e.Cancel = true;
             _FormInstance.Hide();
        }
      }
     _FormInstance.Show();
}

Ответ 5

Я предполагаю, что у вас есть как минимум две формы. Одна форма, назовите ее frmMain, позволяет вам открыть frmOptions. В frmMain добавьте переменную типа frmOptions следующим образом:

public partial class frmMain : Form
{
     private frmOptions optionsInstance = null;
     ...

В рутине, которая открывает диалоговое окно "Параметры", добавьте следующее:

if (optionsInstance == null || !optionsInstance.Visible)
{
     optionsInstance = new frmOptions();
     optionsInstance.Show();
}

Когда frmOptions закрывается, optionsInstance не будет пустым, поэтому вы должны проверить, видимо ли это перед созданием экземпляра frmOptions.

Если это не сработает для вас, вы можете попробовать мьютекс, но это, вероятно, перебор.

Ответ 6

Основываясь на Ответ Jon Skeet, я использую следующий код для отображения формы в виде модального диалогового окна.

        if (this.aboutForm == null)
        {
            this.aboutForm = new AboutForm();
            this.aboutForm.FormClosed += (sender2, e2) => { this.aboutForm = null; };
            this.aboutForm.ShowDialog(this);
        }
        else
        {
            this.aboutForm.Focus();
        }

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

Ответ 7

    Main_Frm _main_Frm = null;

    private void Show_bt_Click(object sender, EventArgs e)
    {

        if (_main_Frm != null)
        {
            _main_Frm .BringToFront();
        }
        else
        {
            _main_Frm = new Comission_Frm();
            _main_Frm .Show();
        }

         //This condition used when you closed the form the form will disposed and when you reopen.
        if (_main_Frm .IsDisposed)
        {
            _main_Frm = new _Main_Frm ();
            _main_Frm .Show();
        }
   }

Ответ 8

Это может помочь! Примечание. Следующий код взят из статьи ниже: https://www.dotnetcurry.com/ShowArticle.aspx?ID=150.

static class Program
    {
        ///<summary>
        /// The main entry point for the application.
        ///</summary>
        [STAThread]
        static void Main()
        {
            bool instanceCountOne = false;

            using (Mutex mtex = new Mutex(true, "MyRunningApp", out instanceCountOne))
            {
                if (instanceCountOne)
                {
                    Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Application.Run(new Form1());
                    mtex.ReleaseMutex();
                }
                else
                {
                    MessageBox.Show("An application instance is already running");
                }
            }
        }
    }