2014-01-12 3 views
2

У меня есть MainWindow, у которого есть его viewmodel MainWindowViewModel. Внутри окна есть одно текстовое поле, которое принимает вход пользователя и несколько переключателей для фильтрации поиска и одной кнопки. Кнопка действия связан с ViewModel, используя команду:Реализовать прогресс в этом простом WPF-приложении

<Button x:Name="btnSearch" Command="{Binding SearchByCommand, Mode=OneWay}" /> 

Внутри ViewModel есть:

public ICommand SearchByCommand 
{ 
    get 
    { 
     if (_SearchByCommand == null) 
     { 
      _SearchByCommand = new RelayCommand(
       x => this.LoadData(this.SearchBy), 
       x => { return !string.IsNullOrEmpty(this.SearchText); } 
      ); 
     } 
     return _SearchByCommand; 
    } 
} 

И LoadData:

private void LoadData(string searchBy) 
{ 
    switch(searchBy) 
    ... 
} 

Это прекрасно работает, но я не» t знать, как реализовать индикатор прогресса в этом решении. Когда пользователь нажимает кнопку поиска, индикатор прогресса должен запуститься и заморозить текущий пользовательский интерфейс. После загрузки данных в методе LoadData прогресс progresscount progressbar должен завершиться и снова включить интерфейс.

ответ

4

Вы можете использовать индикатор занятости из расширенного набора инструментов WPF: here.

Затем вам нужно сделать свою обработку (LoadData) в другом потоке, чтобы не заморозить пользовательский интерфейс. Чтобы сделать это, простой способ заключается в использовании фона рабочего:

Добавить логическое вашему СУС, чтобы указать, когда приложение занято:

private bool isBusy; 
public bool IsBusy 
{ 
    get { return isBusy; } 
    set 
    { 
     this.isBusy = value; 
     this.OnPropertyChanged("IsBusy"); 
    } 
} 

Настройка фона рабочего:

private void LoadData(string searchBy) 
{ 
    IsBusy = true; 
    BackgroundWorker worker = new BackgroundWorker(); 
    worker.DoWork += (o, ea) => 
    { 
     //Do your heavy work here 
    }; 

    worker.RunWorkerCompleted += (o, ea) => 
    { 
     IsBusy = false; 
    }; 

    worker.RunWorkerAsync(); 
} 

Если вы хотите показать индикатор выполнения с текущим ходом обработки, вам нужно сделать немного больше работы. Прежде всего, необходимо применить пользовательский стиль к занятому индикатора:

<toolkit:BusyIndicator IsBusy="True" BusyContent="Processing..." > 
    <extToolkit:BusyIndicator.ProgressBarStyle> 
     <Style TargetType="ProgressBar"> 
      <Setter Property="IsIndeterminate" Value="False"/> 
      <Setter Property="Height" Value="15"/> 
      <Setter Property="Margin" Value="8,0,8,8"/> 
      <Setter Property="Value" Value="{Binding ProgressValue}"/> 
     </Style> 
    </extToolkit:BusyIndicator.ProgressBarStyle> 
</toolkit:BusyIndicator> 

Затем добавить свойство ProgressValue к вашей виртуальной машине:

private int progressValue ; 
public int ProgressValue 
{ 
    get { return progressValue ; } 
    set 
    { 
     this.progressValue = value; 
     this.OnPropertyChanged("ProgressValue "); 
    } 
} 

и сообщать о прогрессе в фоновом режиме работника:

BackgroundWorker worker = new BackgroundWorker(); 
worker.WorkerReportsProgress = true; 
worker.DoWork += (o, ea) => 
    { 
     //Do your heavy work here 
     worker.ReportProgress(10); 

     //Do your heavy work here 
     worker.ReportProgress(20); 

     //And so on 
    }; 

worker.ProgressChanged += (o,ea) => 
    { 
     ProgressValue = e.ProgressPercentage; 
    }; 

worker.RunWorkerCompleted += (o, ea) => 
    { 
     IsBusy = false; 
    }; 
+0

при реализации я получаю ошибку. Вызывающий поток должен быть STA, потому что для этого требуется множество компонентов пользовательского интерфейса. Где указать атрибут [STAThread]? – user1765862

Смежные вопросы