前言
在日常开发过程中,如果遇到需要一段时间才能完成的任务,通常需要给用户一个进度条提示。今天给大家介绍的是WPF/C#中ProgressBar的基本使用。
ProgressBar的介绍
在WPF(Windows Presentation Foundation)中,ProgressBar
是一个用户界面元素,用于显示一个操作的进度。
ProgressBar
有两种模式:确定模式和不确定模式。
- 确定模式:在确定模式下,
ProgressBar
显示一个操作的完成百分比。你可以通过设置ProgressBar
的Minimum
、Maximum
和Value
属性来控制进度条的显示。例如,如果你设置Minimum
为0,Maximum
为100,然后将Value
设置为50,那么ProgressBar
将显示为一半填充(表示操作完成了50%)。 - 不确定模式:在不确定模式下,
ProgressBar
显示一个持续的动画,表示一个操作正在进行,但是没有指定完成百分比。你可以通过设置ProgressBar
的IsIndeterminate
属性为true
来启用不确定模式。
不确定模式的使用
xaml:
<StackPanel> <Button Content="执行耗时任务" Margin="20" Click="Button_Click"></Button> <ProgressBar Margin="50" x:Name="progressBar1" Width="300" Height="20" IsIndeterminate="True" Visibility="Hidden" /> </StackPanel>
cs:
private async void Button_Click(object sender, RoutedEventArgs e) { progressBar1.Visibility = Visibility.Visible; await Task.Delay(5000); progressBar1.Visibility = Visibility.Hidden; }
假设在执行一个耗时任务,可以先将ProgressBar
的IsIndeterminate
属性设置为True
,表示使用不确定模式,也就是进度条一直在动,然后设置Visibility
属性为Hidden
,使ProgressBar
刚开始不可见。在执行任务前,让它可见,再任务完成后,再让它不可见。
实现的效果如下图所示:
确定模式的使用
xaml:
<StackPanel> <Button Content="执行耗时任务" Margin="20" Click="Button_Click"></Button> <ProgressBar Margin="50" x:Name="progressBar1" Width="300" Height="20" Minimum="0" Maximum="100" Visibility="Hidden" /> </StackPanel>
cs:
private async void Button_Click(object sender, RoutedEventArgs e) { progressBar1.Visibility = Visibility.Visible; for (int i = 0; i <= 100; i++) { int progress = i; await Task.Delay(50); // 等待50毫秒 Dispatcher.Invoke(() => progressBar1.Value = progress); // 更新ProgressBar的值 } progressBar1.Visibility = Visibility.Hidden; }
使用
Dispatcher.Invoke(() => progressBar1.Value = progress);
是因为在WPF中,只有创建控件的线程(通常是主UI线程)才能访问该控件。这被称为线程关联或线程亲和性。如果你尝试从另一个线程访问控件,例如从异步任务中更新控件的属性,你将会收到一个异常。
Dispatcher.Invoke
方法允许你在创建控件的线程上执行特定的操作。Dispatcher.Invoke(() => MyProgressBar.Value = progress);
这行代码将更新ProgressBar
的Value
属性的操作发送到主UI线程上执行。这样,即使这个操作是从异步任务中调用的,也不会收到线程亲和性的异常。
总的来说,每当你需要从非UI线程更新UI控件时,你都需要使用Dispatcher.Invoke
或类似的方法来确保操作在正确的线程上执行。
实现效果如下所示:
HandyControl中的ProgressBar的使用
HandyControl是一个基于WPF(Windows Presentation Foundation)的开源UI库,它提供了一套丰富、灵活且实用的控件集,可以帮助开发者更容易地创建美观且功能强大的桌面应用程序。
HandyControl中ProgressBar的使用效果如下所示:
跟自带的用法差不多,现在从三个类别中分别选一种做示例。
不确定模式的用法
对应图中的第二种类别。
xaml:
<StackPanel> <Button Content="执行耗时任务" Margin="20" Click="Button_Click"></Button> <hc:CircleProgressBar x:Name="progressBar1" IsIndeterminate="True" Margin="20" Width="100" Height="100" ArcThickness="6" Visibility="Hidden" Style="{StaticResource ProgressBarInfoCircle}"/> </StackPanel>
cs:
private async void Button_Click(object sender, RoutedEventArgs e) { progressBar1.Visibility = Visibility.Visible; await Task.Delay(5000); progressBar1.Visibility = Visibility.Hidden; }
实现效果如下所示:
确定模式的用法
图中第一种。
xaml:
<StackPanel> <Button Content="执行耗时任务" Margin="20" Click="Button_Click"></Button> <hc:CircleProgressBar x:Name="progressBar1" Visibility="Hidden" Margin="20" ShowText="True" Width="80" Height="80" ArcThickness="5" Style="{StaticResource ProgressBarSuccessCircle}"/> </StackPanel>
cs:
private async void Button_Click(object sender, RoutedEventArgs e) { progressBar1.Visibility = Visibility.Visible; for (int i = 0; i <= 100; i++) { int progress = i; await Task.Delay(50); // 等待50毫秒 Dispatcher.Invoke(() => progressBar1.Value = progress); // 更新ProgressBar的值 } progressBar1.Visibility = Visibility.Hidden; }
实现效果:
图中第三种。
xaml:
<StackPanel> <Button Content="执行耗时任务" Margin="20" Click="Button_Click"></Button> <hc:WaveProgressBar x:Name="progressBar1" /> </StackPanel>
cs:
private async void Button_Click(object sender, RoutedEventArgs e) { progressBar1.Visibility = Visibility.Visible; for (int i = 0; i <= 100; i++) { int progress = i; await Task.Delay(50); // 等待50毫秒 Dispatcher.Invoke(() => progressBar1.Value = progress); // 更新ProgressBar的值 } progressBar1.Visibility = Visibility.Hidden; }
实现效果:
总结
本文介绍了WPF/C#中ProgressBar控件的基本使用,该控件有两种使用方式,分别为确实模式与不确定模式,确实模式就是知道进度是如何变化的,不确定模式就是不确定进度的变化情况,进度条一直在动,由于自带的ProgressBar只有条形的,可能无法满足日常的开发需求,因此跟大家介绍了HandyControl中ProgressBar的用法,在HandyControl的进度条有其他样式。希望对正在学习WPF的同学有所帮助。