Загрузить всплывающую форму поперечной нити - PullRequest
0 голосов
/ 20 мая 2018

У меня проблемы с манипулированием формами из другого потока.

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

Это неправильный способ сделать это.У меня есть 3 проблемы, которые возникают при использовании этого метода

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

Если кто-то могНаправь меня в правильном направлении.В настоящее время мой код выглядит следующим образом:

На главной форме Загрузить:

        CallerIDfrm = new frmCallerID();
        CallerIDfrm.Show();
        CallerIDfrm.Hide();

для управления всплывающим окном. Я использую

    delegate void StringArgReturningVoidDelegate1(string CallerIDnum, string CallerIDname, string ContactID);
    private void CallerID(string CallerIDnum, string CallerIDname, string ContactID)
    {
        if (CallerIDfrm.InvokeRequired)
        {
            StringArgReturningVoidDelegate1 d = new StringArgReturningVoidDelegate1(CallerID);
            CallerIDfrm.Invoke(d, new object[] { CallerIDnum, CallerIDname, ContactID });
        }
        else
        {

            if (ContactID != null || ContactID != "0")
            {
                CallerIDfrm.ContactID = ContactID;


            }
            CallerIDfrm.Mainfrm = this;
            CallerIDfrm.TopLevel = true;
            CallerIDfrm.TopMost = true;
            CallerIDfrm.lblCallerIDname.Text = CallerIDname;
            CallerIDfrm.lblCallerIDnum.Text = CallerIDnum;
            CallerIDfrm.Show();
            CallerIDOpen = true;

        }
    }

Чтобы скрыть всплывающее окно, пока не потребуется снова, я использую:

delegate void StringArgReturningVoidDelegate2();

private void CallerIDClose()
{
    if (CallerIDfrm.InvokeRequired)
    {
        StringArgReturningVoidDelegate2 d = new StringArgReturningVoidDelegate2(CallerIDClose);
        CallerIDfrm.Invoke(d, new object[] { });
    }
    else
    {
        try
        {
            CallerIDfrm.Hide();
            CallerIDOpen = false;
        }
        catch
        {
        }
    }
}

Я пробовал иначе, но всплывающее окно загружается так, как будто оно не отвечает, и я теряю доступ к всплывающему окну.

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

1 Ответ

0 голосов
/ 21 мая 2018

Что я понял из вашего вопроса: у вас есть вызывающий api / lib / class, и вы хотели бы показать CallerId во всплывающей форме при получении вызова.Взгляните на События и программирование, управляемое событиями .

Следующие коды не были проверены, я написал это из головы.Может не скомпилироваться, они здесь, чтобы показать пример:

Создайте событие CallReceived в классе api / lib следующим образом:

public event EventHandler<CallReceivedEventArgs> CallReceived;
protected void OnCallReceived(EventArgs e)
{
    var handler = CallReceived;
    if (handler != null)
        handler(this, e);

    // Note: For C# 6.0 and later, above statements can be simplified to
    // CallReceived?.Invoke(this, e);
}

Примечание: Если вы неУ вас нет доступа к этому коду api / lib, создайте класс Gateway и поместите туда ваше событие вместе с механизмом его запуска.

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

public class CallReceivedEventArgs : EventArgs
{
    public string CallerIDnum {get; set;}
    public string CallerIDname {get; set;}
    public string ContactID {get; set;}
}

Теперь, в вашем классе api / lib, вызывайте это событие при получении вызова:

// a call received, replace dummy values with actual values
OnCallReceived(new CallReceivedEventArgs() { CallerIDnum="5554443322", CallerIDname="SOME_NAME", ContactID="SOME_CONTACT" });

Наконец, в форме GUI, зарегистрируйтесь науказанное событие и процесс соответственно.

// inside your main form class
private CallerAPI callerApi = new CallerAPI();

// somewhere inside you main form class, register to event
// from your use case, I would place it inside Main Form's constructor
callerApi.CallReceived += callerApi_Callreceived;

// receive event
void callerApi_Callreceived(object sender, CallReceivedEventArgs e)
{
    var callerIDnum = e.CallerIDnum;
    // etc.
    // show callerId form with details
    // you need to change frmCallerID's constructor accordingly
    CallerIDfrm = new frmCallerID(e.CallerIDnum, CallerIDname, ContantID);
    // to be able to track opened popups, you can store them inside a list
    // private List<Form> openPopupList = new List<Form>();
    //
    // alternatively, you can assign CallerIDnum to form's name property
    // and store these inside a List<string> instead of List<Form>
    openPopupList.add(CallerIDfrm);
    CallerIDfrm.Show();
}

Не забудьте отменить регистрацию события.

callerApi.CallReceived -= callerApi_Callreceived;

Чтобы обернуть его:

  1. Я не могу вызвать другое всплывающее окно. Мне нужно использовать тот, который я создал во время выполнения

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

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

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

Мне нужно использовать переменную bool для удержания, если всплывающее окно открыто или нет.

Лучшим подходом было бы: зарегистрироваться в форме FormClosed событие и удалить из openPopupListсоответственно.

frmCallerID.FormClosed += frmCallerID_FormClosed;

void frmCallerID_FormClosed(object sender, EventArgs e)
{
    // remove form from openPopupList
    frmCallerID closedPopup = (frmCallerID) sender;
    openPopupList.remove(closedPopup);
}
...