Как получить окно из дескриптора в WPF

У меня есть пользовательский интерфейс WPF, при нажатии кнопки я запускаю потоки. Я хочу прочитать несколько значений txtbox в пользовательском интерфейсе из потока и хочу обновить текстовое поле в пользовательском интерфейсе со статусом потока

Я пытаюсь передать дескриптор пользовательского интерфейса потоку и вернуть окно из дескриптора (как мы это делаем в MFC) и обновить пользовательский интерфейс.

Я могу получить дескриптор как «IntPtr ParentHandle = new WindowInteropHelper (this) .Handle;»

Но не знаю, как вытащить окно из-под ручки.

OR

Есть ли другой способ обновить и получить значения в пользовательском интерфейсе WPF из потока.


person somaraj    schedule 13.08.2009    source источник


Ответы (1)


Не нужно использовать ручки. Просто передайте ссылки на объекты. Вы можете создать поток, используя класс ParameterizedThreadStart, который принимает параметр object. Таким образом, вы можете определить объект, содержащий элементы для всех значений, которые вы хотите передать потоку, вместо того, чтобы поток извлекал их из пользовательского интерфейса. Кроме того, вы можете передать ссылку на свой класс окна, поэтому, когда поток будет завершен (или для обновления статуса), вы можете просто использовать эту ссылку (не забудьте использовать Диспетчер для обновления элементов управления (в WinForms вы бы сделали this.Invoke).

Это могло выглядеть так:

public class WPFWindow ...
{
    private class ThreadData
    {
        public int Value1;
        public string Value2;
        public WPFWindow Window;
    }

    ....

    private void StartThread()
    {
        ThreadData tdata = new ThreadData();
        tdata.Value1 = 42;
        tdata.Value2 = "Hello World!";
        tdata.Window = this;

        Thread t = new Thread(new ParameterizedThreadStart(ThreadMethod));
        t.Start(tdata);
    }

    private void ThreadMethod(object data)
    {
        ThreadData tdata = (ThreadData)data;

        // ... process values here

        // Update controls
        if(tdata.Window.textbox.Dispatcher.CheckAccess())
        {
            // The calling thread owns the dispatcher, and hence the UI element
            tdata.Window.textbox.AppendText(...);
        }
        else
        {
            // Invokation required
            tdata.Window.textbox.Dispatcher.Invoke(DispatcherPriority.Normal, delegate);
        }
    }
}

Обратите внимание, что я пишу это вслепую, не тестируя это в WPF. Однако в WinForms я всегда так делаю.

person Thorsten Dittmar    schedule 13.08.2009
comment
спасибо за ответ, всего один вопрос, какова будет реализация delgate в другом случае - person somaraj; 13.08.2009
comment
Делегат (который также может быть анонимным методом) просто обновит соответствующий элемент управления. Я думаю, вы также можете проверить Диспетчер для самого окна, а затем поместить все элементы управления обновлением кода в делегат. Образец можно найти здесь: ascealedguard.com/2007 / 08 / - person Thorsten Dittmar; 13.08.2009