XAML
<UserControl x:Class="WpfApp1.UC_ProgressBarEx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="200" d:DesignWidth="1000">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="Boolean2VisibilityConverter"/>
</UserControl.Resources>
<Grid>
<Border Background="White" BorderBrush="Gray" BorderThickness="1">
<Border Background="White" BorderThickness="1">
<Grid>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFE5E5E5" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Grid Width="{Binding ProgressBarWidth, FallbackValue=200, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" HorizontalAlignment="Left" MinHeight="6">
<Grid.Background>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FF8BBA91" Offset="0"/>
<GradientStop Color="#FF8BBA91" Offset="1"/>
<GradientStop Color="#FF9ED76A" Offset="0.8"/>
<GradientStop Color="#FF9ED76A" Offset="0.2"/>
</LinearGradientBrush>
</Grid.Background>
</Grid>
<Border>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#89E2E2E2" Offset="0"/>
<GradientStop Color="#C1FFFFFF" Offset="0.5"/>
<GradientStop Color="Transparent" Offset="0.52"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" x:Name="txtPercent"
Text="{Binding Percentage, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Visibility="{Binding PercentageVisible, Converter={StaticResource Boolean2VisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
/>
</Grid>
</Border>
</Border>
</Grid>
</UserControl>

CS
public partial class UC_ProgressBarEx : UserControl
{
/// <summary>
/// 百分比最后是否显示,默认true显示
/// </summary>
private readonly bool _bInitVisibility;
public UC_ProgressBarEx()
{
InitializeComponent();
_bInitVisibility = true;
ProgressBarWidth = 0;
}
/// <summary>
/// 进度条最小值
/// </summary>
public double Minimum
{
get { return (double)GetValue(MinimumProperty); }
set { SetValue(MinimumProperty, value); }
}
public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register("Minimum", typeof(double), typeof(UC_ProgressBarEx), new PropertyMetadata(0d, OnMinimumChanged));
private static void OnMinimumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as UC_ProgressBarEx).Update();
}
/// <summary>
/// 进度条最大值
/// </summary>
public double Maximum
{
get { return (double)GetValue(MaximumProperty); }
set { SetValue(MaximumProperty, value); }
}
public static readonly DependencyProperty MaximumProperty = DependencyProperty.Register("Maximum", typeof(double), typeof(UC_ProgressBarEx), new PropertyMetadata(100d, OnMaximumChanged));
private static void OnMaximumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as UC_ProgressBarEx).Update();
}
/// <summary>
/// 进度值
/// </summary>
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(UC_ProgressBarEx), new PropertyMetadata(0d, OnValueChanged));
private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as UC_ProgressBarEx).Update();
}
/// <summary>
/// 百分比是否显示,默认true显示
/// </summary>
public bool PercentageVisible
{
get { return (bool)GetValue(PercentageVisibleProperty); }
set { SetValue(PercentageVisibleProperty, value); }
}
public static readonly DependencyProperty PercentageVisibleProperty =
DependencyProperty.Register("PercentageVisible", typeof(bool), typeof(UC_ProgressBarEx), new PropertyMetadata(true));
/// <summary>
/// 要显示的数据
/// </summary>
public string Percentage
{
get { return (string)GetValue(PercentageProperty); }
private set { SetValue(PercentageProperty, value); }
}
public static readonly DependencyProperty PercentageProperty = DependencyProperty.Register("Percentage", typeof(string), typeof(UC_ProgressBarEx), new PropertyMetadata("0%", OnPercentageChanged));
private static void OnPercentageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as UC_ProgressBarEx).Update();
}
/// <summary>
/// 进度条宽度
/// </summary>
public double ProgressBarWidth
{
get { return (double)GetValue(ProgressBarWidthProperty); }
private set { SetValue(ProgressBarWidthProperty, value); }
}
private static readonly DependencyProperty ProgressBarWidthProperty = DependencyProperty.Register("ProgressBarWidth", typeof(double), typeof(UC_ProgressBarEx), null);
private void Update()
{
ProgressBarWidth = Math.Min((Value / (Maximum - Minimum) * this.ActualWidth) - 2, this.ActualWidth - 2);
txtPercent.Margin = new Thickness(ProgressBarWidth - 50, 0, 0, 0);
var val = (Value / (Maximum - Minimum) * 100);
if (val >= 100.00)
{
Percentage = "100 %";
ThreadPool.QueueUserWorkItem(ThreadProc);
}
else
{
Percentage = val.ToString("0.00") + "%";
}
}
private void ThreadProc(object state)
{
Thread.Sleep(1000);
if (_bInitVisibility)
{
this.Dispatcher.Invoke(() =>
{
Visibility = Visibility.Visible;
});
}
else
{
this.Dispatcher.Invoke(() =>
{
Visibility = Visibility.Collapsed;
});
}
}
}
测试
int Sum = 345;
//pbCompleted.PercentageVisible = false;
pbCompleted.Maximum = Sum;
pbCompleted.Value = 0;
lbResult.Text = $"({pbCompleted.Value}/{pbCompleted.Maximum})";
Task.Run(() =>
{
//for (int i = 0; i < 5; i++)
//{
// this.Dispatcher.Invoke(() =>
// {
// pbCompleted.Value = 20 * i * pbCompleted.Maximum / 100;
// });
// Thread.Sleep(300);
//}
for (int i = 0; i < Sum; i++)
{
this.Dispatcher.Invoke(() =>
{
pbCompleted.Value++;
lbResult.Text = $"({pbCompleted.Value}/{pbCompleted.Maximum})";
});
Thread.Sleep(20);
}
this.Dispatcher.Invoke(() =>
{
btn.IsEnabled = true;
});
});
