WPF进度条渲染

Xaml中:

<Window.Resources>

<local:BorderClipConverter x:Key="BorderClipConverter" />

<Style x:Key="BorderClip" TargetType="{x:Type Border}">

<Setter Property="UIElement.Clip">

<Setter.Value>

<MultiBinding Converter="{StaticResource BorderClipConverter}">

<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}" />

<Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}" />

<Binding Path="CornerRadius" RelativeSource="{RelativeSource Self}" />

</MultiBinding>

</Setter.Value>

</Setter>

</Style>

</Window.Resources>

<Grid>

<ProgressBar

Width="570"

Height="28"

Margin="0,68,0,0"

Value="100">

<ProgressBar.Resources>

<Style TargetType="ProgressBar">

<Setter Property="BorderThickness" Value="0" />

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type ProgressBar}">

<Border

Name="TemplateRoot"

Background="{TemplateBinding Background}"

BorderBrush="{TemplateBinding BorderBrush}"

BorderThickness="{TemplateBinding BorderThickness}"

CornerRadius="20">

<Grid>

<Rectangle Name="PART_Track" />

<Border

Name="PART_Indicator"

HorizontalAlignment="Left"

Background="#ECECEC"

CornerRadius="20"

Style="{StaticResource BorderClip}">

<Grid>

<Rectangle

Name="PART_GlowRect"

Width="100"

HorizontalAlignment="Left"

Fill="#19BE6B"

RadiusX="20"

RadiusY="20" />

<Rectangle

Name="Animation"

Fill="{TemplateBinding Foreground}"

RenderTransformOrigin="0.5,0.5"

Visibility="Collapsed">

<Rectangle.RenderTransform>

<TransformGroup>

<ScaleTransform />

</TransformGroup>

</Rectangle.RenderTransform>

</Rectangle>

</Grid>

</Border>

</Grid>

</Border>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</ProgressBar.Resources>

</ProgressBar>

<Button

Height="28"

Click="Button_Click"

Content="进度条百分" />

<ProgressBar

Name="progressBar1"

Width="570"

Height="28"

Margin="0,200,0,0" >

<ProgressBar.Resources>

<Style TargetType="{x:Type ProgressBar}">

<Setter Property="Background" Value="#19BE6B" />

<Setter Property="FontSize" Value="30" />

<Setter Property="Padding" Value="5,0" />

<Setter Property="Template">

<Setter.Value>

<ControlTemplate TargetType="{x:Type ProgressBar}">

<Grid>

<Border

Background="#ECECEC"

BorderThickness="0"

CornerRadius="20" />

<Grid Margin="{TemplateBinding BorderThickness}">

<Rectangle x:Name="PART_Track" />

<Border

x:Name="PART_Indicator"

HorizontalAlignment="Left"

ClipToBounds="True"

Style="{StaticResource BorderClip}">

<Grid RenderTransformOrigin="0.5,0.5">

<Grid.RenderTransform>

<TransformGroup>

<ScaleTransform ScaleX="1" ScaleY="-1" />

<SkewTransform AngleX="0" AngleY="0" />

<RotateTransform Angle="180" />

<TranslateTransform />

</TransformGroup>

</Grid.RenderTransform>

<Border Background="{TemplateBinding Background}" CornerRadius="20">

<Viewbox

Margin="{TemplateBinding Padding}"

HorizontalAlignment="Left"

SnapsToDevicePixels="True"

StretchDirection="DownOnly">

<TextBlock

VerticalAlignment="Center"

FontSize="{TemplateBinding FontSize}"

Foreground="#ffffff"

RenderTransformOrigin="0.5,0.5"

SnapsToDevicePixels="True"

Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, StringFormat={}{0}%}">

<TextBlock.RenderTransform>

<TransformGroup>

<ScaleTransform ScaleX="-1" ScaleY="1" />

<SkewTransform AngleX="0" AngleY="0" />

<RotateTransform Angle="0" />

<TranslateTransform />

</TransformGroup>

</TextBlock.RenderTransform>

</TextBlock>

</Viewbox>

</Border>

<Border

BorderBrush="#000000"

BorderThickness="1"

CornerRadius="20"

Opacity="0.1" />

</Grid>

</Border>

</Grid>

</Grid>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</ProgressBar.Resources>

</ProgressBar>

</Grid>

CS中:

public class BorderClipConverter : IMultiValueConverter
{
public object Convert(object\[\] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length == 3)
{
object obj = values0;
if (obj is double)
{
double num = (double)obj;
obj = values1;
if (obj is double)
{
double num2 = (double)obj;
obj = values2;
if (obj is CornerRadius)
{
CornerRadius cornerRadius = (CornerRadius)obj;
if (num < double.Epsilon || num2 < double.Epsilon)
{
return Geometry.Empty;
}

PathGeometry pathGeometry = new PathGeometry();
pathGeometry.Figures = new PathFigureCollection
{
new PathFigure(new Point(cornerRadius.TopLeft, 0.0), new PathSegment8
{
new LineSegment(new Point(num - cornerRadius.TopRight, 0.0), isStroked: false),
new ArcSegment(new Point(num, cornerRadius.TopRight), new Size(cornerRadius.TopRight, cornerRadius.TopRight), 90.0, isLargeArc: false, SweepDirection.Clockwise, isStroked: false),
new LineSegment(new Point(num, num2 - cornerRadius.BottomRight), isStroked: false),
new ArcSegment(new Point(num - cornerRadius.BottomRight, num2), new Size(cornerRadius.BottomRight, cornerRadius.BottomRight), 90.0, isLargeArc: false, SweepDirection.Clockwise, isStroked: false),
new LineSegment(new Point(cornerRadius.BottomLeft, num2), isStroked: false),
new ArcSegment(new Point(0.0, num2 - cornerRadius.BottomLeft), new Size(cornerRadius.BottomLeft, cornerRadius.BottomLeft), 90.0, isLargeArc: false, SweepDirection.Clockwise, isStroked: false),
new LineSegment(new Point(0.0, cornerRadius.TopLeft), isStroked: false),
new ArcSegment(new Point(cornerRadius.TopLeft, 0.0), new Size(cornerRadius.TopLeft, cornerRadius.TopLeft), 90.0, isLargeArc: false, SweepDirection.Clockwise, isStroked: false)
}, closed: false)
};
pathGeometry.Freeze();
return pathGeometry;
}
}
}
}

return DependencyProperty.UnsetValue;
}

public object\[\] ConvertBack(object value, Type\[\] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}

事件方法

private void Button_Click(object sender, RoutedEventArgs e)
{
//测试代码
Thread thread = new Thread(new ThreadStart(() =>
{
for (int i = 0; i <= 100; i++)
{
this.progressBar1.Dispatcher.BeginInvoke((ThreadStart)delegate { this.progressBar1.Value = i; });
Thread.Sleep(300);
}
}));
thread.Start();
//测试代码
}

相关推荐
LinXunFeng3 小时前
Obsidian - 使用 Share Note 分享笔记并自部署
前端·笔记·github
乘风gg6 小时前
为什么AI 时代来临,大部分人吃不到红利
前端·ai编程·claude
恋猫de小郭7 小时前
Android 限制侧载新进展,谷歌联合国内厂商推验证计划
android·前端·flutter
IT_陈寒7 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
恋猫de小郭7 小时前
解读 Android 17 全新内存限制,有没有“豁免”后门?
android·前端·flutter
Hyyy8 小时前
理解LLM的基本工作原理:预训练、微调、推理的区别
前端
Gatlin9 小时前
前端逆向与反逆向:一场猫鼠游戏的底层逻辑与实战
前端
代码煮茶9 小时前
React 组件封装方法论 —— 以 Todo App 为例
javascript·react.js
Pedantic9 小时前
本地通知(Local Notifications)学习笔记
前端
任沫9 小时前
Agent之Function Call
javascript·人工智能·go