Как обновить текстовое поле в новом окне, открытом новой веткой? - PullRequest
0 голосов
/ 06 ноября 2011

Я могу открыть новое окно в новой теме с помощью следующего кода.

Следующий код взят из файла MainWindow.xaml.cs

private void buttonStartStop_Click(object sender, RoutedEventArgs e)
{    

  Test test = new Test();

  Thread newWindowThread = new Thread(new ThreadStart(test.start));
  newWindowThread.SetApartmentState(ApartmentState.STA);
  newWindowThread.IsBackground = true;
  newWindowThread.Start();
}

и следующего из теста.start ()

public void start()
{

  OutputWindow outputwindow = new OutputWindow();
  outputwindow.Show();


  Output.print("Begin");
  System.Windows.Threading.Dispatcher.Run();
  Output.print("FINAL");
  System.Windows.Threading.Dispatcher.Run();

}

И следующее из класса Output

public static void print(String str)
{
  Dispatcher uiDispatcher = OutputWindow.myOutputWindow.Dispatcher;
  uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.AppendText(str + "\n"); }));
  uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.ScrollToLine(OutputWindow.myOutputWindow.textBoxOutput.LineCount - 1); }));
}

public static void printOnSameLine(String str)
{
  Dispatcher uiDispatcher = OutputWindow.myOutputWindow.Dispatcher;
  uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.AppendText(str); }));
  uiDispatcher.BeginInvoke(new Action(delegate() { OutputWindow.myOutputWindow.textBoxOutput.ScrollToLine(OutputWindow.myOutputWindow.textBoxOutput.LineCount - 1); }));
}

"Begin" печатается в текстовом поле, но "FINAL" нет, я хочу начатьметод в классе Test для обновления текстового поля в outputwindow через программу.Каков наилучший способ сделать это?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 07 ноября 2011

В идеале поток (поток пользовательского интерфейса), который создает элементы пользовательского интерфейса, тоже владеет элементами.В диспетчере все, что вы делаете, - это отправляете обработку, не связанную с пользовательским интерфейсом, в фоновый поток.Как только фоновый процесс завершен, результат снова будет передан обратно в основной поток пользовательского интерфейса.Для примера примера проверьте: http://weblogs.asp.net/pawanmishra/archive/2010/06/06/understanding-dispatcher-in-wpf.aspx

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

Я не уверен, что ты пытаешься сделать. Обычно FINAL не печатает, потому что вы вызвали System.Windows.Threading.Dispatcher.Run (). Этот метод поддерживает поток и прослушивает события. Вы можете посмотреть на это так, как если бы у вас было while (true) {} внутри метода Run. Метод будет продолжать работать до тех пор, пока Dispatcher не будет остановлен. Вы должны поддерживать фоновый поток и вызывать ваши статические методы из другого потока, когда вам нужно установить сообщение. Вот пример:

        // reference to window in another thread
        Window outputWindow = null;

        Thread thread = new Thread(() =>
        {
            // another thread
            outputWindow = new Window();
            outputWindow.Show();
            // run event loop
            System.Windows.Threading.Dispatcher.Run();
        }) { ApartmentState = ApartmentState.STA, IsBackground = true };
        thread.Start();

        while (outputWindow == null)
        {
            // wait until the window in another thread has been created
            Thread.Sleep(100);
        }

        // simulate process
        for (int i = 0; i < 10; i++)
        {
            outputWindow.Dispatcher.BeginInvoke((Action)(() => { outputWindow.Title = i.ToString(); }), System.Windows.Threading.DispatcherPriority.Normal);
            Thread.Sleep(500); // simulate some hard work so we can see the change on another window's title
        }

        // close the window or shutdown dispatcher or abort the thread...
        thread.Abort();

EDIT:

Это может быть быстрое и грязное общее решение. DoSomeHardWork создает другой поток GUI для окна ожидания, в котором отображается информация о ходе выполнения. Это окно создает рабочий поток, который фактически выполняет работу. Работа реализована в методе Action. Первый аргумент - это окно ожидания, поэтому вы можете изменить его из рабочего потока. Конечно, в реальном мире вы должны проходить через интерфейс, а не напрямую к реализации окна, но это только пример. Второй аргумент - это объект, так что вы можете передать все, что вам нужно, в рабочий поток. Если вам нужно больше аргументов, передайте object [] или измените сигнатуру метода. В этом примере я симулирую тяжелую работу со счетчиком и сном. Вы можете выполнить этот код по нажатию кнопки несколько раз, и вы увидите, что все окна ожидания подсчитывают свой счетчик без остановки. Вот код:

    public static void DoSomeHardWork(Action<Window, object> toDo, object actionParams)
    {
        Thread windowThread = new Thread(() =>
        {
            Window waitWindow = new Window();
            waitWindow.Loaded += (s, e) =>
            {
                Thread workThread = new Thread(() =>
                {
                    // Run work method in work thread passing the
                    // wait window as parameter
                    toDo(waitWindow, actionParams);
                }) { IsBackground = true };
                // Start the work thread.
                workThread.Start();
            };
            waitWindow.Show();
            Dispatcher.Run();
        }) { ApartmentState = ApartmentState.STA, IsBackground = true };
        // Start the wait window thread.
        // When window loads, it will create work thread and start it.
        windowThread.Start();
    }

    private void MyWork(Window waitWindow, object parameters)
    {
        for (int i = 0; i < 10; i++)
        {
            // Report progress to user through wait window.
            waitWindow.Dispatcher.BeginInvoke((Action)(() => waitWindow.Title = string.Format("{0}: {1}", parameters, i)), DispatcherPriority.Normal);
            // Simulate long work.
            Thread.Sleep(500);
        }
        // The work is done. Shutdown the wait window dispather.
        // This will stop listening for events and will eventualy terminate
        // the wait window thread.
        waitWindow.Dispatcher.InvokeShutdown();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        DoSomeHardWork(MyWork, DateTime.Now);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...