Обратная передача текста события из многопоточного класса в Windows ActiveForm - PullRequest
0 голосов
/ 21 октября 2011

Так что у меня есть интересная проблема (для меня в любом случае).Я пишу приложение, которое запускает сканирование и отправляет информацию из класса обратно в форму Windows.Сейчас я создаю экземпляр формы, обращаюсь к ActiveForm, а затем публикую некоторый текст в общедоступной функции в этой форме.

Scan.cs

// Sets the text of scan history in the ui
private void SetScanHistory(string text)
{
    MyWinForm1 form = (MyWinForm1)MyWinForm1.ActiveForm;

    if (form != null)
    {
        form.SetText(text);
    }
}

MyWinForm1.cs

// Sets the text of txtScanHistory to the text 
public void SetText(string text)
{
    this.Invoke((MethodInvoker)delegate
    {
        // txtScanHistory is a TextBox
        txtScanHistory.Text += text + Environment.NewLine;
    });
}

Так что сейчас это работает довольно хорошо.Проблема в том, что когда пользователь меняет фокус с формы Windows, текст перестает обновляться, поэтому у меня появляется «if (form! = Null)».Я знаю, что это не идеальный способ сделать то, что я пытаюсь сделать, поэтому мой вопрос заключается в том, как я могу изменить этот код, чтобы он был чем-то вроде настраиваемого события в «MyWinForm1»?Или, если есть какой-то другой способ сделать это, я хотел бы увидеть некоторые альтернативы.

Ответы [ 2 ]

1 голос
/ 26 октября 2011

Есть несколько способов достичь того, чего вы хотите.

1) Вы можете добавить ссылку на целевую форму как свойство класса Scan.cs

    public MyWinForm1 WinFormReference { get; set; }

    // Sets the text of scan history in the ui
    private void SetScanHistory(string text)
    {
        if (this.WinFormReference != null)
        {
            this.WinFormReference.SetText(text);
        }
    }

тогда вы можете передать ссылку на ваш класс сканирования в экземпляр WinForm1 и установить соответствующее свойство [в этом случае я передаю класс сканера с помощью конструктора WinForm]:

  public void WinForm1(Scan scanner)
  {
      if (scanner != null) scanner.WinFormReference = this;
  }

2) Вы можете добавить пользовательское событие в класс сканирования, а затем подключить делегата к обратному вызову в вашей WinForm [опять же, вашей WinForm потребуется ссылка на ваш класс сканирования]:

public class SetScanHistoryEvents: EventArgs
{
    public SetScanHistoryEvents(string text)
    {
        this.Text = text;
    }

    public string Text { get; set; }
}

public class Scan
{
    public event EventHandler<SetScanHistoryEvents> ScanHistoryEvent;

    // Sets the text of scan history in the ui
    private void SetScanHistory(string text)
    {
        if (this.ScanHistoryEvent != null)
        {
            this.ScanHistoryEvent(this, new SetScanHistoryEvents(text));
        }
    }
}

Затем вы подключаете обратный вызов в конструкторе вашей формы (или в другом месте):

    public MyWinForm1(Scan scanner)
    {
        if (scanner != null)
            scanner.ScanHistoryEvent += new EventHandler<SetScanHistoryEvents>(scanner_ScanHistoryEvent);
    }

    private void scanner_ScanHistoryEvent(object sender, SetScanHistoryEvents e)
    {
        this.Invoke((MethodInvoker)delegate
        {
            // txtScanHistory is a TextBox
            txtScanHistory.Text += text + Environment.NewLine;
        });
    }
0 голосов
/ 22 октября 2011

Вы можете иметь что-то вроде следующего, которое использует SynchronizationContext

public partial class Form1 : Form
    {
        SynchronizationContext context;
        public Form1()
        {
            InitializeComponent();
            context = SynchronizationContext.Current;
        }
        // Sets the text of scan history in the ui
        private void SetScanHistory(string text)
        {
            CallFunc(text);
        }
        private void CallFunc(string TextValue)
        {            
            context.Post(new SendOrPostCallback(
            delegate
            {
                textBox1.Text += TextValue + Environment.NewLine;
            }), TextValue);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...