日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

WPF實現圓形進度條的示例代碼_C#教程

作者:驚鏵 ? 更新時間: 2023-02-10 編程語言

WPF 實現圓形進度條

  • 框架使用.NET40
  • Visual Studio 2019;
  • CircularProgressBar?繼承?ProgressBar,在?XAML?中創建兩個?Path?的?Data?設置?ArcSegment?修改第二個控件的?Point?,設置?StartPoint = new Point(Size.Width, 0)?設置起點。
  • 創建依賴屬性?Angle?作為修改?ArcSegment?的?Point?作為進度條的圓的閉合。
  • 當進度條?ValueChanged?時創建?DoubleAnimation?動畫,修改?Angle?。

示例代碼

1)?CircularProgressBar.xaml?代碼如下:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                    xmlns:controls="clr-namespace:WPFDevelopers.Controls"
                    xmlns:convert="clr-namespace:WPFDevelopers.Converts">
    
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <convert:AngleToPointConverter x:Key="prConverter"/>
    <convert:AngleToIsLargeConverter x:Key="isLargeConverter"/>
    <Style TargetType="{x:Type controls:CircularProgressBar}" BasedOn="{StaticResource ControlBasicStyle}">
        <Setter Property="Maximum" Value="100"/>
        <Setter Property="StrokeThickness" Value="10"/>
        <Setter Property="Foreground" Value="{DynamicResource InfoSolidColorBrush}"/>
        <Setter Property="Background" Value="{DynamicResource PrimaryNormalSolidColorBrush}"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <!--<Setter Property="Width" Value="100"/>
        <Setter Property="Height" Value="100"/>-->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:CircularProgressBar}">
                    <controls:SmallPanel Width="{Binding ElementName=PART_Path,Path=ActualWidth}" 
                            Height="{Binding ElementName=PART_Path,Path=ActualHeight}"
                            HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalAlignment}">
                        <Canvas>
                            <Path Stroke="{TemplateBinding BorderBrush}"
                              StrokeThickness="{TemplateBinding BrushStrokeThickness}"
                                  x:Name="PART_Path">
                                <Path.Data>
                                    <PathGeometry>
                                        <PathFigure x:Name="PART_PathFigure">
                                            <ArcSegment SweepDirection="Clockwise"
                                                    IsLargeArc="True"
                                                    x:Name="PART_ArcSegment">
                                            </ArcSegment>
                                        </PathFigure>
                                    </PathGeometry>
                                </Path.Data>
                            </Path>
                            <Path Stroke="{TemplateBinding Background}" 
                              StrokeThickness="{TemplateBinding StrokeThickness}">
                                <Path.Data>
                                    <PathGeometry>
                                        <PathFigure x:Name="PART_PathFigureAngle">
                                            <ArcSegment SweepDirection="Clockwise"
                                                    IsLargeArc="{Binding Path=Angle, Converter={StaticResource isLargeConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
                                                    x:Name="PART_ArcSegmentAngle">
                                                <ArcSegment.Point>
                                                    <MultiBinding Converter="{StaticResource prConverter}">
                                                        <Binding Path="Angle" RelativeSource="{RelativeSource FindAncestor, AncestorType=ProgressBar}"/>
                                                        <Binding Path="Size" RelativeSource="{RelativeSource FindAncestor, AncestorType=ProgressBar}"/>
                                                    </MultiBinding>
                                                </ArcSegment.Point>
                                            </ArcSegment>
                                        </PathFigure>
                                    </PathGeometry>
                                </Path.Data>
                            </Path>
                        </Canvas>
                        <TextBlock Foreground="{TemplateBinding Foreground}" 
                                   Text="{Binding Path=Value, StringFormat={}{0}%, 
                                RelativeSource={RelativeSource TemplatedParent}}"
                                   FontSize="{TemplateBinding FontSize}"
                                   VerticalAlignment="Center"
                                   HorizontalAlignment="Center"
                                   x:Name="PART_TextBlock"/>
                    </controls:SmallPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

2)?CircularProgressBar.xaml.cs?代碼如下:

using?System;
using?System.Windows;
using?System.Windows.Controls;
using?System.Windows.Media;
using?System.Windows.Media.Animation;

namespace?WPFDevelopers.Controls
{
????[TemplatePart(Name?=?ArcSegmentTemplateName,?Type?=?typeof(ArcSegment))]
????[TemplatePart(Name?=?ArcSegmentAngleTemplateName,?Type?=?typeof(ArcSegment))]
????[TemplatePart(Name?=?PathFigureTemplateName,?Type?=?typeof(PathFigure))]
????[TemplatePart(Name?=?PathFigureAngleTemplateName,?Type?=?typeof(PathFigure))]
????[TemplatePart(Name?=?TextBlockTemplateName,?Type?=?typeof(TextBlock))]
????public?class?CircularProgressBar?:?ProgressBar
????{
????????private?const?string?ArcSegmentTemplateName?=?"PART_ArcSegment";
????????private?const?string?ArcSegmentAngleTemplateName?=?"PART_ArcSegmentAngle";
????????private?const?string?PathFigureTemplateName?=?"PART_PathFigure";
????????private?const?string?PathFigureAngleTemplateName?=?"PART_PathFigureAngle";
????????private?const?string?TextBlockTemplateName?=?"PART_TextBlock";
????????private?ArcSegment?_arcSegment,?_arcSegmentAngle;
????????private?PathFigure?_pathFigure,?_pathFigureAngle;
????????private?TextBlock?_textBlock;


????????public?static?readonly?DependencyProperty?SizeProperty?=
???????????DependencyProperty.Register("Size",?typeof(Size),?typeof(CircularProgressBar),
???????????????new?PropertyMetadata(new?Size(50,50)));
????????public?static?readonly?DependencyProperty?AngleProperty?=
????????????DependencyProperty.Register("Angle",?typeof(double),?typeof(CircularProgressBar),
????????????????new?PropertyMetadata(0.0));

????????public?static?readonly?DependencyProperty?StrokeThicknessProperty?=
????????????DependencyProperty.Register("StrokeThickness",?typeof(double),?typeof(CircularProgressBar),
????????????????new?PropertyMetadata(10.0));

????????public?static?readonly?DependencyProperty?BrushStrokeThicknessProperty?=
????????????DependencyProperty.Register("BrushStrokeThickness",?typeof(double),?typeof(CircularProgressBar),
????????????????new?PropertyMetadata(1.0));

????????public?CircularProgressBar()
????????{
????????????ValueChanged?+=?CircularProgressBar_ValueChanged;
????????}
????????public?override?void?OnApplyTemplate()
????????{
????????????base.OnApplyTemplate();
???????????
????????????if?(Size.Width?!=?Size.Height)
????????????{
????????????????var?max?=?Math.Max(Size.Width,?Size.Height);
????????????????Size?=?new?Size(max,?max);
????????????}
???????????
????????????_pathFigure?=?GetTemplateChild(PathFigureTemplateName)?as?PathFigure;
????????????_pathFigureAngle?=?GetTemplateChild(PathFigureAngleTemplateName)?as?PathFigure;
????????????_pathFigure.StartPoint?=?new?Point(Size.Width,?0);
????????????_pathFigureAngle.StartPoint?=?new?Point(Size.Width,?0);
????????????_arcSegment?=?GetTemplateChild(ArcSegmentTemplateName)?as?ArcSegment;
????????????_arcSegment.Size?=?Size;
????????????_arcSegment.Point?=?new?Point(Size.Width?-?0.000872664626,?7.61543361704753E-09);
????????????_arcSegmentAngle?=?GetTemplateChild(ArcSegmentAngleTemplateName)?as?ArcSegment;
????????????_arcSegmentAngle.Size?=?Size;
????????????_textBlock?=?GetTemplateChild(TextBlockTemplateName)?as?TextBlock;
????????????if?(Size.Width?<?15)
????????????{
????????????????FontSize?=?8;
????????????}
????????}
????????
????????public?Size?Size
????????{
????????????get?=>?(Size)GetValue(SizeProperty);
????????????set?=>?SetValue(SizeProperty,?value);
????????}

????????public?double?Angle
????????{
????????????get?=>?(double)GetValue(AngleProperty);
????????????set?=>?SetValue(AngleProperty,?value);
????????}

????????public?double?StrokeThickness
????????{
????????????get?=>?(double)GetValue(StrokeThicknessProperty);
????????????set?=>?SetValue(StrokeThicknessProperty,?value);
????????}

????????public?double?BrushStrokeThickness
????????{
????????????get?=>?(double)GetValue(BrushStrokeThicknessProperty);
????????????set?=>?SetValue(BrushStrokeThicknessProperty,?value);
????????}

????????private?void?CircularProgressBar_ValueChanged(object?sender,?RoutedPropertyChangedEventArgs<double>?e)
????????{
????????????var?bar?=?sender?as?CircularProgressBar;
????????????var?currentAngle?=?bar.Angle;
????????????var?targetAngle?=?e.NewValue?/?bar.Maximum?*?359.999;
????????????var?anim?=?new?DoubleAnimation(currentAngle,?targetAngle,?TimeSpan.FromMilliseconds(500));
????????????bar.BeginAnimation(AngleProperty,?anim,?HandoffBehavior.SnapshotAndReplace);
????????}
????}
}

3)?AngleToPointConverter.cs?代碼如下:

using?System;
using?System.Globalization;
using?System.Windows;
using?System.Windows.Data;

namespace?WPFDevelopers.Converts
{
????internal?class?AngleToPointConverter?:?IMultiValueConverter
????{
????????public?object?Convert(object[]?values,?Type?targetType,?object?parameter,?CultureInfo?culture)
????????{
????????????var?angle?=?(double)values[0];
????????????var?size?=?(Size)values[1];
????????????var?radius?=?(double)size.Height;
????????????var?piang?=?angle?*?Math.PI?/?180;

????????????var?px?=?Math.Sin(piang)?*?radius?+?radius;
????????????var?py?=?-Math.Cos(piang)?*?radius?+?radius;
????????????return?new?Point(px,?py);
????????}
????????public?object[]?ConvertBack(object?value,?Type[]?targetTypes,?object?parameter,?CultureInfo?culture)
????????{
????????????throw?new?NotImplementedException();
????????}
????}
}

4)?AngleToIsLargeConverter.cs?代碼如下:

using?System;
using?System.Globalization;
using?System.Windows.Data;

namespace?WPFDevelopers.Converts
{
????internal?class?AngleToIsLargeConverter?:?IValueConverter
????{
????????public?object?Convert(object?value,?Type?targetType,?object?parameter,?CultureInfo?culture)
????????{
????????????var?angle?=?(double)value;
????????????return?angle?>?180;
????????}

????????public?object?ConvertBack(object?value,?Type?targetTypes,?object?parameter,?CultureInfo?culture)
????????{
????????????throw?new?NotImplementedException();
????????}
????}
}

5)?CircularMenuExample.xaml?代碼如下:

<UserControl?x:Class="WPFDevelopers.Samples.ExampleViews.CircularMenuExample"
?????????????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"?
?????????????xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
?????????????xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
?????????????xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
?????????????mc:Ignorable="d"?
?????????????d:DesignHeight="450"?d:DesignWidth="800">
????<controls:CodeViewer>
????????<StackPanel?Background="Black">
????????<TextBlock?Text="微信公眾號:WPFDevelopers"?FontSize="40"
???????????????????????????Foreground="#A9CC32"?FontWeight="Bold"
???????????????????????????Margin="50,10,0,20"/>
????????<wpfdev:CircularMenu?ItemsSource="{Binding?MenuArray,RelativeSource={RelativeSource?AncestorType=local:CircularMenuExample}}"?
?????????????????????????????SelectionChanged="CircularMenu_SelectionChanged"/>
????</StackPanel>
????????<controls:CodeViewer.SourceCodes>
????????????<controls:SourceCodeModel?
????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/CircularMenuExample.xaml"?
????????????????CodeType="Xaml"/>
????????????<controls:SourceCodeModel?
????????????????CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/CircularMenuExample.xaml.cs"?
????????????????CodeType="CSharp"/>
????????</controls:CodeViewer.SourceCodes>
????</controls:CodeViewer>
</UserControl>

效果圖

原文鏈接:https://mp.weixin.qq.com/s/1ql9MCQqK2TfKGIoBtYXVw

欄目分類
最近更新