WPF - Как смоделировать операцию цикла в пользовательском интерфейсе - PullRequest
0 голосов
/ 30 мая 2011

Я создаю утилиту quick'n'dirty, которая позволит редактировать данные, считываемые последовательно из набора файлов. Вот очень упрощенное объяснение того, что произойдет за одну итерацию цикла:

  • Считать строку из входного потока
  • Синтаксический анализ и использование проанализированных результатов для заполнения элементов управления формы
  • Разрешить редактирование пользователя и ждать подтверждения нажатия кнопки
  • Получить обновленные значения элемента управления формы и записать в выходной поток

Что я не могу понять, так это как интегрировать цикл обработки с управляемым событиями пользовательским интерфейсом. Например, как приостановить работу цикла во время ожидания ввода пользователя.

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

Спасибо за любые идеи, которые вы можете предложить. Тим

Ответы [ 2 ]

0 голосов
/ 30 мая 2011

Я могу придумать два подхода для этого:

  • Возможно, проще всего использовать модальное диалоговое окно: когда ваш рабочий поток требует ввода от пользователя, отобразите диалоговое окно, котороеэто операция блокировкиПримерно так:

    // Worker thread loop
    while(...)
    {
        ...
    
        // prompt user for data (invoke synchronously on UI thread)
        UserData data = (UserData)window.Invoke(PromptUserData);
    
        ...
    }
    
    ...
    
    
    
    UserData PromptUserData()
    {
        UserInputDialog dlg = new UserInputDialog();
        dlg.ShowDialog();
        return dlg.UserData;
    }
    
  • Другой вариант, если вы не хотите использовать модальное диалоговое окно, это использовать дескриптор ожидания для синхронизации рабочего потока и пользовательского интерфейса:

    приватный только для чтения AutoResetWaitHandle _userInputWaitHandle = new AutoResetWaitHandle (false);

    ...
    
    // Worker thread loop
    while(...)
    {
        ...
    
        // Setup the UI to allow user input
        window.Invoke(SetupUIForInput);
        // Wait for the input to be validated
        _userInputWaitHandle.WaitOne();
        ...
    }
    
    
    ...
    
    void SetupUIForInput()
    {
        // Enable the UI
        inputForm.Enabled = true;
    
        // Whatever else you need to do...
        ...
    }
    
    
    void buttonOK_Click(object sender, EventArgs e)
    {
        // Signal the worker thread to continue
        _userInputWaitHandle.Set();
    }
    
0 голосов
/ 30 мая 2011

Вы бы не реализовали цикл в узком смысле.
Вы бы сделали что-то вроде этого (псевдокод):

OnStartOperationButtonClick()
{
    if(!ReadLine())
        return;
    ParseLineAndPopulateControls();
    ShowEditingControls();
}

OnConfirmationButtonClick()
{
    GetControlValuesAndWriteToOutputStream();
    if(!ReadLine())
    {
        HideEditingControls();
        return;
    }

    ParseLineAndPopulateControls();
}

Нет необходимости в отдельном потоке, учитывая , что чтение и анализ строки не займет много времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...