<Window x:Class="PrograssBarNet.ProgressBarPrimary"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PrograssBarNet"
        mc:Ignorable="d"
        Title="ProgressBarPrimary" Height="100" Width="900" WindowStartupLocation="CenterScreen" Background="Transparent" Foreground="Transparent"
        WindowStyle="None" AllowsTransparency="True"  Topmost="True">
    <Window.Resources>
        <ResourceDictionary>
            <!--进度条-->
            <SolidColorBrush x:Key="ProgressBar.Progress" Color="#FF2564F9"/>
            <SolidColorBrush x:Key="ProgressBar.Background" Color="#FFB9B9B9"/>
            <SolidColorBrush x:Key="ProgressBar.Border" Color="#FFDEDEDE"/>
            <Style x:Key="BaseProgressBar" TargetType="{x:Type ProgressBar}">
                <Setter Property="Foreground" Value="{StaticResource ProgressBar.Progress}"/>
                <Setter Property="Background" Value="{StaticResource ProgressBar.Background}"/>
                <Setter Property="BorderBrush" Value="{StaticResource ProgressBar.Border}"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Border.CornerRadius" Value="13"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ProgressBar}">
                            <Grid x:Name="TemplateRoot">
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Determinate"/>
                                        <VisualState x:Name="Indeterminate">
                                            <Storyboard RepeatBehavior="Forever">
                                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="Animation">
                                                    <EasingDoubleKeyFrame KeyTime="0" Value="0.25"/>
                                                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.25"/>
                                                    <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0.25"/>
                                                </DoubleAnimationUsingKeyFrames>
                                                <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="Animation">
                                                    <EasingPointKeyFrame KeyTime="0" Value="-0.5,0.5"/>
                                                    <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,0.5"/>
                                                    <EasingPointKeyFrame KeyTime="0:0:2" Value="1.5,0.5"/>
                                                </PointAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="{TemplateBinding Border.CornerRadius}"/>
                                <Border x:Name="PART_Track" MinWidth="20" CornerRadius="{TemplateBinding Border.CornerRadius}"/>
                                <Grid x:Name="PART_Indicator" ClipToBounds="true" HorizontalAlignment="Left">
                                    <Border x:Name="Indicator" MinWidth="20" Background="{TemplateBinding Foreground}" CornerRadius="{TemplateBinding Border.CornerRadius}"/>
                                    <Border x:Name="Animation" MinWidth="20" Background="{TemplateBinding Foreground}"
                                            CornerRadius="{TemplateBinding Border.CornerRadius}" RenderTransformOrigin="0.5,0.5">
                                        <Border.RenderTransform>
                                            <TransformGroup>
                                                <ScaleTransform/>
                                                <SkewTransform/>
                                                <RotateTransform/>
                                                <TranslateTransform/>
                                            </TransformGroup>
                                        </Border.RenderTransform>
                                        <TextBlock HorizontalAlignment="Right"  VerticalAlignment="Center"  Foreground="#FFFFFF" FontSize="13"
                                                   Margin="0,0,10,0">
                                            <Run Text="{Binding RelativeSource={RelativeSource TemplatedParent},Path=Tag}"/>
                                            <Run Text="%"/>
                                        </TextBlock>
                                    </Border>
                                    <!--发光板-->
                                    <Border ClipToBounds="True" >
                                        <Border Width="{Binding PART_Track.Width}" Name="border1" Margin="-100,0">
                                            <Border.Background>
                                                <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5" Opacity="0.4">
                                                    <GradientStop Color="{TemplateBinding Foreground}" Offset="0"/>
                                                    <GradientStop Color="#FFD8E4FB" Offset="0"/>
                                                    <GradientStop Color="{TemplateBinding Foreground}" Offset="1"/>
                                                </LinearGradientBrush>
                                            </Border.Background>
                                        </Border>
                                    </Border>
                                </Grid>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="Orientation" Value="Vertical">
                                    <Setter Property="LayoutTransform" TargetName="TemplateRoot">
                                        <Setter.Value>
                                            <RotateTransform Angle="-90"/>
                                        </Setter.Value>
                                    </Setter>
                                </Trigger>
                                <Trigger Property="IsIndeterminate" Value="true">
                                    <Setter Property="Visibility" TargetName="Indicator" Value="Collapsed"/>
                                </Trigger>
                                <EventTrigger RoutedEvent="UserControl.Loaded">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Duration="0:0:2" To="1" Storyboard.TargetName="border1"
                                                             Storyboard.TargetProperty="Background.GradientStops[1].Offset"
                                                             RepeatBehavior="Forever"
                                                             AutoReverse="True"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
    <Border CornerRadius="20" Background="Transparent" >
        <ProgressBar Name="baseProgressBar" Height="40" Maximum="100" Value="0"  Style="{DynamicResource BaseProgressBar}" Background="Transparent" Tag="0" />
    </Border>
</Window>

2、在新的线程中启动并设置值

    public partial class ProgressBarPrimary : Window
        public ProgressBarPrimary()
            InitializeComponent();
        public void SetBarValue(double i)
            Action<DependencyProperty, object> update = this.baseProgressBar.SetValue;
            Dispatcher.Invoke(update, DispatcherPriority.Normal, new object[] { System.Windows.Controls.Primitives.RangeBase.ValueProperty, i });
            Dispatcher.Invoke(update, DispatcherPriority.Normal, new object[] { System.Windows.Controls.Primitives.RangeBase.TagProperty, i });
    public class ProgressBarHelper
        public static ProgressBarHelper _ = new ProgressBarHelper();
        private Thread thread;
        public void Show()
            thread = new Thread(() =>
                  var progressBar = new ProgressBarPrimary();
                  progressBar.Show();
                  for (int i = 0; i < 100; i++)
                      progressBar.SetBarValue(i);
                      Thread.Sleep(200);
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        public void Close()
            thread?.Abort();

3、进度根据计算得到的函数

        double GetTagValue(double i)
            return i == this.baseProgressBar.Maximum ? 100 : Math.Round(100 / this.baseProgressBar.Maximum * i);

4、刷新界面的方法,目前还没感觉到作用

        void DoEvents()
            var frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(ExitFrames), frame);
                Dispatcher.PushFrame(frame);
            catch (InvalidOperationException)
        private object ExitFrames(object frame)
            ((DispatcherFrame)frame).Continue = false;
            return null;
    /// <summary>
    /// ProgressBarPrimary.xaml 的交互逻辑
    /// </summary>
    public partial class ProgressBarPrimary : Window
        public ProgressBarPrimary(double maxMinum)
            InitializeComponent();
            this.baseProgressBar.Maximum = maxMinum;
        public void SetBarValue(double i)
            Action<DependencyProperty, object> update = this.baseProgressBar.SetValue;
            Dispatcher.Invoke(update, DispatcherPriority.Normal, new object[] { System.Windows.Controls.Primitives.RangeBase.ValueProperty, i });
            Dispatcher.Invoke(update, DispatcherPriority.Normal, new object[] { System.Windows.Controls.Primitives.RangeBase.TagProperty, GetTagValue(i) });
            DoEvents();
        double GetTagValue(double i)
            return i == this.baseProgressBar.Maximum ? 100 : Math.Round(100 / this.baseProgressBar.Maximum * i);
        void DoEvents()
            var frame = new DispatcherFrame();
            Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                new DispatcherOperationCallback(ExitFrames), frame);
                Dispatcher.PushFrame(frame);
            catch (InvalidOperationException)
        private object ExitFrames(object frame)
            ((DispatcherFrame)frame).Continue = false;
            return null;
    /// <summary>
    /// 进度条的帮助类
    /// </summary>
    public class ProgressBarHelper:IDisposable
        public static ProgressBarHelper _ = new ProgressBarHelper();
        public Thread thread;
        public string PipeName = "PipesOfProgressBar";
        /// <summary>
        /// 显示进度条
        /// </summary>
        /// <param name="maxminum">最大进度值</param>
        public void Show(double maxminum)
            thread = new Thread(() =>
                  var progressBar = new ProgressBarPrimary(maxminum);
                  progressBar.Show();
                  var server = new NamedPipeServerStream(PipeName);
                      server.WaitForConnection();
                      StreamReader reader = new StreamReader(server);
                      double result = 0;
                          var line = reader.ReadLine();
                          if (double.TryParse(line, out result))
                              if (result <= maxminum)
                                  progressBar.SetBarValue(result);
                                  break;
                              break;
                      } while (result < maxminum);
                      reader.Close();
                      server.Disconnect();
                      Thread.Sleep(3000);
                  catch { }
                  finally { server.Dispose(); }
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        /// <summary>
        /// 关闭进度条
        /// </summary>
        public void Close()
            if(thread!=null && thread.IsAlive)
                int count = 0;//等待线程运行结束,最多等待3秒
                while (thread.ThreadState != ThreadState.Stopped && count<=3000)
                    Thread.Sleep(100);
                    count += 100;
                thread.Abort();
            writer?.Close();
            client?.Dispose();
        NamedPipeClientStream client;
        StreamWriter writer;
        private bool disposedValue;
        /// <summary>
        /// 连接管道
        /// </summary>
        public void ConnectPipe()
            client = new NamedPipeClientStream(PipeName);
            client.Connect(10000);
            writer = new StreamWriter(client);
        /// <summary>
        /// 循环向管道内写入值,如果input大于进度条的最大值,抛出异常
        /// </summary>
        /// <param name="input">进度条的Value</param>
        public void Run(double input)
            writer.WriteLine(input);
            writer.Flush();
        protected virtual void Dispose(bool disposing)
            if (!disposedValue)
                Close();
                // TODO: 释放未托管的资源(未托管的对象)并重写终结器
                // TODO: 将大型字段设置为 null
                disposedValue = true;
        //实现析构函数,使没有调用close 方法 或者dispose 方法时进度条会被关闭
        // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
        ~ProgressBarHelper()
            // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
            Dispose(disposing: false);
        public void Dispose()
            // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
            Dispose(disposing: true);
            GC.SuppressFinalize(this);

控制台程序调用方法

        static void Main(string[] args)
            ProgressBarHelper._.Show(50);
            ProgressBarHelper._.ConnectPipe();
            for (int i = 1; i <=50; i++)
                ProgressBarHelper._.Run(i);
                Thread.Sleep(100);
            ProgressBarHelper._.Close();
            //ProgressBarHelper._.Dispose();