Неопределенный индикатор прогресса
В настоящее время у меня есть кнопка, которая, когда пользователь нажимает на нее, ищет конкретный дисковод CD-ROM, который готов и содержит файл. Иногда, когда пользователь нажимает на кнопку, нажатие кнопки происходит нажатием кнопки мыши, и программа зависает на неопределенное время, пока компьютер не прочитает привод CD-ROM.
Я сделал мой индикатор, но я заметил несколько вещей:
1) Программа зависает / зависает до вызова метода, который проверяет диски. Поэтому я не могу установить индикатор выполнения при вызове метода. Похоже, что программа зависает, когда кнопка нажата и пользователь одновременно вставляет компакт-диск. Как я могу отобразить индикатор выполнения, как только кнопка будет нажата, а мышь еще не нажата / пока система не обнаружит дисковод компакт-дисков?
2) Я запутался в том, как реализовать Background Worker. Я посмотрел понравившиеся примеры, но ни один из них не соответствовал наличию неопределенного индикатора выполнения с подходом MVVM (без кода).
3) Как заставить окно исчезнуть после завершения операции? В настоящее время у меня есть кнопка отмены (безусловно, не полезно).
Вот что я настроил до сих пор. Не уверен, как продолжить:
Индикатор:
<Grid>
<Border BorderBrush="Black" BorderThickness="2" CornerRadius="4" Background="#EEEEEE" HorizontalAlignment="Left" Height="110" VerticalAlignment="Top" Width="295" />
<StackPanel>
<Label x:Name="lblProgress"/>
<ProgressBar x:Name="progress" Height="25" Width="270" IsIndeterminate="True" Foreground="Green"></ProgressBar>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="225,10,0,0" RenderTransformOrigin="0.083,0.526">
<Button x:Name="btnCancel" Width="60" Content="Cancel" Command="{Binding CloseCommand}"/>
</StackPanel>
</StackPanel>
</Grid>
У меня есть ProgressBarViewModel, который содержит команду, которая позволяет пользователю отменить окно прогресса. Также у меня есть другая ViewModel, которая мне нужна для вызова диалога progressBar внутри, но я не уверен, где его вызывать, потому что если я вызываю его внутри моего Метод, кнопка все еще висит без отображения индикатора выполнения.
Я заметил, что если я использую метод Button_PreviewMouseDown в codebehind, однако, индикатор выполнения отображается правильно, когда мышь не работает, и система отображает индикатор выполнения, но я не хочу использовать codebehind, потому что индикатор выполнения отображается в другом представлении.
В настоящее время для моей кнопки импорта все, что прикреплено, это команда, которая вызывает метод, который ищет дисководы для привода CD-ROM.
MainViewModel:
public ICommand ImportCDFilePathCommand
{
get
{
return new RelayCommand(ImportCDFilePath, null);
}
}
private void ImportCDFilePath()
{
// dialogService.ShowDialog("Progress", progressBarWindow); <---Does not get called until the operation is done
//Gets all the drives
DriveInfo[] allDrives = DriveInfo.GetDrives();
//checks if any CD-Rom exists in the drives
var cdRomExists = allDrives.Any(x => x.DriveType == DriveType.CDRom);
// Get all the cd roms
var cdRoms = allDrives.Where(x=>x.DriveType==DriveType.CDRom && allDrives.Any(y=>y.IsReady));
//.... There is other code that is commented out too long and not necessary
}
РЕДАКТИРОВАТЬ:
Некоторые попытки использования BackgroundWorker:
static BackgroundWorker _bw = new BackgroundWorker();
//constructor
MainViewModel() {
_bw.DoWork += bw_DoWork;
_bw.RunWorkerAsync("Message to worker");
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
// This is called on the worker thread
Console.WriteLine(e.Argument); // writes "Message to worker"
// Perform time-consuming task...
ImportCDFilePath();
}
Ошибка, которую я получаю:
The calling thread must be STA, because many UI components require this.