【发布时间】:2014-07-29 17:51:15
【问题描述】:
目前,我有一个按钮,当用户单击它时,它会查找已准备好并包含文件的特定 CD-ROM 驱动器。有时,当用户单击一个按钮时,该按钮单击是鼠标按下,程序会挂起一段不确定的时间,直到计算机读取 CD-ROM 驱动器。
我创建了进度条,但我注意到了一些事情:
1) 程序在调用检查 cd 驱动器的方法之前挂起/冻结。所以我无法设置调用方法时显示的进度条。似乎程序在单击按钮时和用户同时放入 CD 时挂起。单击按钮并且鼠标仍然向下/直到系统检测到 cd 驱动器时,如何显示进度条?
2) 我对如何实现后台工作人员感到困惑。我看起来很喜欢示例,但没有一个与 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 方法,但是当鼠标按下并且系统确实显示进度条时进度条会正确显示,但我不想使用代码隐藏,因为我在另一个中有进度条看法。
目前,对于我的导入按钮,附加的只是一个命令,该命令调用一个搜索驱动器以查找 CD-ROM 驱动器的方法。
主视图模型:
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.
【问题讨论】:
-
线程/异步 ImportReagentLotFilePath。之后在 UI 线程上报告进度条。
-
我不确定您使用的是哪个框架,但如果您使用的是 4.5+,这将是完美的异步方法。另一种选择是使用 BackgroundWorker,或者只是在您的方法中创建并启动一个线程。
-
我使用的是 .NET 4.5。为什么使用 Async vs. Background Worker?
标签: c# wpf mvvm progress-bar backgroundworker