Форма одного экземпляра, но не единичная - PullRequest
1 голос
/ 06 ноября 2008

Я не могу понять, как это возможно. Пожалуйста, помогите !!

У меня есть приложение с трайконом. Я хочу, чтобы форма отображалась, когда пользователь дважды щелкает на панели задач. У меня проблема с тем, что можно получить 2 или более форм, отображая быстрый тройной или четырехкратный щелчок по трейкону. Причина, по которой я не хочу синглтона, заключается в том, что я хочу, чтобы форма выпускалась каждый раз, когда она закрыта, чтобы сохранить память, может быть, это не очень хорошая идея?

У меня есть поле с именем m_form1. У меня есть метод с именем ShowForm1; Я вызываю метод ShowForm1 по двойному щелчку TrayIcon.

        private Form1 m_form1;
        private void ShowForm1()
        {
            if (m_form1 == null)
            {
                Trace.WriteLine("*CREATE*" + Thread.CurrentThread.ManagedThreadId.ToString());
                m_form1 = new Form1();
                m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
                m_form1.Show();
            }
            m_form1.BringToFront();
            m_form1.Activate();
        }

Таким образом, когда Form1 требуется некоторое время для создания, тогда можно создать 2, потому что m_form1 все еще равен нулю, когда поступает второй вызов. Блокировка, похоже, не работает, так как это один и тот же поток при обоих вызовах (я предполагаю, что поток пользовательского интерфейса), то есть трассировка дважды записывает * CREATE * 1 (ниже).

[3560] *CREATE*1 
[3560] *CREATE*1 

Изменение кода для включения оператора блокировки мне не помогает.

    private Form1 m_form1;
    private object m_Locker = new object();
    private void ShowForm1()
    {
        lock (m_Locker)
        {
            if (m_form1 == null)
            {
                Trace.WriteLine("****CREATE****" + Thread.CurrentThread.ManagedThreadId.ToString());
                m_form1 = new Form1();
                m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
                m_form1.Show();
            }
        }
        m_form1.BringToFront();
        m_form1.Activate();
    }

Как мне справиться с этой ситуацией?

Спасибо, ребята

Тим.

Ответы [ 3 ]

5 голосов
/ 06 ноября 2008

У вас есть дополнительная логическая переменная m_formUnderConstruction, которую вы проверяете перед построением формы, и которую вы устанавливаете, как только решите ее создать.

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

private Form1 m_form1;
private bool m_underConstruction = false;

private void ShowForm1()
{
    if (m_underConstruction)
    {
        // We're about to show it anyway
        return;
    }
    m_underConstruction = true;
    try
    {
        if (m_form1 == null)
        {
            m_form1 = new Form1();
            m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
            m_form1.Show();
        }
    }
    finally
    {
        m_underConstruction = false;
    }
    m_form1.BringToFront();
    m_form1.Activate();
}
0 голосов
/ 29 декабря 2008

Пожалуйста, посмотрите, он обрабатывает все комбинации событий мыши для NotifyIcon, а также Form1.

Подробнее здесь: http://code.msdn.microsoft.com/TheNotifyIconExample

0 голосов
/ 06 ноября 2008

Используйте Interlocked.Increment, чтобы изменить номер попытки. Если это 1, откройте форму, в противном случае, не. И используйте Interlocked.Decrement после теста или при закрытии формы.

private int openedForms = 0;
private Form1 m_form1;
private void ShowForm1()
{

    if (Interlocked.Increment(ref openedForms) = 1)
    {
       m_form1 = new Form1();
       m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
       m_form1.Show();
    }
    else
    {
       Interlocked.Decrement(ref openedForms);
    }
    if (m_form1 != null)
    {
       m_form1.BringToFront();
       m_form1.Activate();
    }
}

private void m_form1_FormClosed(object Sender, EventArgs args)
{
   Interlocked.Decrement(ref openedForms);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...