Надлежащий путь в WPF MVVM для запуска потоковой задачи поиска

Если Вы отключаете панель, al средства управления на нем отключены также.

Рекурсивное решение с анонимными методами:

type
  TControlProc = reference to procedure (const AControl: TControl);

procedure TForm6.ModifyControl(const AControl: TControl; 
  const ARef: TControlProc);
var
  i : Integer;
begin
  if AControl=nil then
    Exit;
  if AControl is TWinControl then begin
    for i := 0 to TWinControl(AControl).ControlCount-1 do
      ModifyControl(TWinControl(AControl).Controls[i], ARef);
  end;
   ARef(AControl);
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  ModifyControl(Panel1,
    procedure (const AControl: TControl)
    begin
      AControl.Enabled := not Panel1.Enabled;
    end
  );
end;
7
задан Firoso 18 August 2009 в 16:06
поделиться

3 ответа

Я использую поток BackgroundProcess, чтобы делать такие вещи.

Вот ссылка на MSDN по этому поводу: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Дополнительная информация по этому поводу.

Вы иметь три СОБЫТИЯ, связанных с вашим объектом BackgroundProcess: DoWork, ReportProgress и WorkCompleted.

Теперь, чтобы использовать это - и использовать его с наблюдаемой коллекцией - вы захотите сообщить объекту BackgroundProcess, чтобы он мог ОТЧЕТАТЬ О ПРОГРЕССЕ ( это логическое свойство, которое я всегда явно устанавливаю вместе с разрешающей отменой).

Теперь, чтобы начать процесс, вы вызовете метод RunWorkerAsync. Этот метод имеет возможность принимать переменную OBJECT в случае, если вам нужно передать ей данные (если вы хотите более 1 значения, создайте структуру для передачи в RunWorkerAsync).

RunWorkerAsync запускает событие DoWork, поэтому управление переходит к обработчику событий DoWork. Вот (очищенный) код, из которого я его использую:

Dim dt As System.Data.DataTable
dt = da.GetDataTable(sql, System.Data.CommandType.Text, params)
For Each row As System.Data.DataRow In dt.Rows
   If loadQuestionsWorker.CancellationPending Then
       e.Cancel = True
       Exit Sub
   End If
   Dim item As New DataObject
   // Assign Item Values
   backgroundProcessObject.ReportProgress(1, item)
Next

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

Теперь в моем обработчике событий ProgressChanged (метод ReportProgress вызывает событие ProgressChanged) элемент управления снова в руках потока пользовательского интерфейса, поэтому я могу делать такие вещи, как повлиять на пользовательский интерфейс и добавить элемент, о котором я сообщаю, в ObservableCollection.

8
ответ дан 6 December 2019 в 23:11
поделиться

Вы можете явно запустить новый поток или BackgroundWorker , либо использовать ThreadPool . Я не знаю ни одного рекомендуемого способа сделать это в MVVM ...

Если ваша асинхронная операция заполняет ObservableCollection, привязанную к элементу управления, обратите внимание, что вы не можете добавлять элементы к нему в другом потоке. Это нужно сделать в потоке диспетчера элемента управления. Или вы также можете использовать эту коллекцию , которая вызывает событие CollectionChanged в соответствующем потоке

2
ответ дан 6 December 2019 в 23:11
поделиться
var t = new Thread((ThreadStart)delegate
{
    DoWork(...)
    Dispatcher.BeginInvoke((Action)delegate
    {
          SomethingOntheUiThread(...)
          FinishedWork(...);
    }
});

t.Start();
1
ответ дан 6 December 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: