Currently, I have a button that when the user clicks on it, it looks for a specific CD-ROM drive that is ready and contains a file. Sometimes, when the user clicks on a button, the button click is mouse down and the program hangs for an indeterminate time until the computer reads the CD-ROM drive.
I made my progress bar but I noticed a few things:
1) The program hangs/freezes before the method that checks the cd drives gets called. So I can't set the progress bar to display when the method is called. Seems like the program hangs when the button is clicked on and while the user puts in the CD at the same time. How can I display the progress bar as soon as the button is clicked and the mouse is still down/until the system detects the cd drive?
2) I'm confused on how to implement Background Worker. I looked liked examples but none of them matched having an indeterminate progress bar with MVVM (No code behind) approach.
3) How do I make the window disappear after the operation is done? Currently, I have a cancel button (Definitely not useful).
Here's what I have set up so far. Not sure how to continue:
Progress Bar:
<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>
I have a ProgressBarViewModel that contains the command that allows the user to cancel the progress window.Also, I have another ViewModel that I need to call the progressBar Dialog inside but I'm not sure where to call it because if I call it inside my method, the button still hangs without displaying a progressbar.
I noticed if I use Button_PreviewMouseDown method in codebehind, however, the progress bar appears correctly when the mouse is down and the system does display the progress bar but I don't want to use codebehind because I have the progress bar in another view.
Currently, for my import button, all that is attached is a command that calls a method that searches drives for a CD-ROM drive.
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
}
EDIT:
Some attempts using 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();
}
Error I get:
The calling thread must be STA, because many UI components require this.
See Question&Answers more detail:
os