WPF circle progress bar

前端 未结 2 1439
抹茶落季
抹茶落季 2021-02-05 14:18

I want to replace the regular ProgressBar with circle one and after shot search here in the forum i found what i want.

CircularProgressBar.XAML



        
相关标签:
2条回答
  • 2021-02-05 14:37

    You probably missed x:Name="userControl" in the UserControl definition:

    <UserControl x:Name="userControl" x:Class="DesignInControl.CircularProgressBar"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
        <Grid>
            <Path x:Name="pathRoot" Stroke="{Binding SegmentColor, ElementName=userControl}" StrokeThickness="{Binding StrokeThickness, ElementName=userControl}" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Path.Data>
                 ...
    
    0 讨论(0)
  • 2021-02-05 14:54

    This demonstrates how to animate the circle.

    When AnimateProgressCircle is true, the "busy" circle will be rotating, else it will be invisible.

    <!-- "I'm Busy" Animation circle. -->
    <StackPanel Height="20" Width="20">
        <Viewbox>
            <!-- All this does is display the circle. -->
            <local:CircularProgressBar HorizontalAlignment="Center" VerticalAlignment="Center" 
                                       Percentage="0" SegmentColor="#726873" StrokeThickness="10">
                <!-- All this does is continuously animate circle angle from 0 - 100% in response to "IfAnimateProgressCircle". -->
                <local:CircularProgressBar.Style>
                    <Style TargetType="local:CircularProgressBar">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IfAnimateProgressCircle}" Value="True">
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation
                                                    Storyboard.TargetProperty="Percentage"
                                                    From="0" 
                                                    To="100" 
                                                    Duration="0:0:1" 
                                                    AutoReverse="True"
                                                    RepeatBehavior = "Forever"
                                                    />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.EnterActions>
                                <DataTrigger.ExitActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetProperty="Percentage" To="0.0" Duration="0:0:0" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.ExitActions>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </local:CircularProgressBar.Style>
            </local:CircularProgressBar>
        </Viewbox>
    </StackPanel>
    

    Advantages

    • As it's wrapped in a <Viewbox>, it will always be perfectly sized to the parent container.
    • Unlike other simplistic solutions, it does not consume resources when it is not in use because the animation is stopped.

    Testing

    Tested on:

    • WPF
    • .NET 4.5 + .NET 4.6.1
    • Win7 x64
    • Visual Studio 2015 + Update 2

    To test, set DataContext="{Binding RelativeSource={RelativeSource Self}}" in the <Window> tag, then use this code behind.

    You should see the circle pause for 2 seconds, then animate for 4 seconds, then stop.

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private bool _ifAnimateProgressCircle;
    
        public MainWindow()
        {
            InitializeComponent();
            Task.Run(
                async () =>
                {
                    // Animates circle for 4 seconds.
                    IfAnimateProgressCircle = false;
                    await Task.Delay(TimeSpan.FromMilliseconds(2000));
                    IfAnimateProgressCircle = true;
                    await Task.Delay(TimeSpan.FromMilliseconds(6000));
                    IfAnimateProgressCircle = false;
                });
        }
    
        public bool IfAnimateProgressCircle
        {
            get { return _ifAnimateProgressCircle; }
            set { _ifAnimateProgressCircle = value; OnPropertyChanged(); }
        }
    
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
    

    Links that helped with this solution

    • WPF. How to stop data trigger animation through binding?
    • Animate UserControl in WPF?
    • Binding objects defined in code-behind
    • Triggers collection members must be of type EventTrigger
    0 讨论(0)
提交回复
热议问题