Add project files.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls.Primitives;
|
||||
|
||||
namespace TheXamlGuy.UI.WPF.Controls;
|
||||
|
||||
public class ProgressRing : RangeBase
|
||||
{
|
||||
public static readonly DependencyProperty IsActiveProperty =
|
||||
DependencyProperty.Register(nameof(IsActive),
|
||||
typeof(bool), typeof(ProgressRing), new PropertyMetadata(true, OnIsActivePropertyChanged));
|
||||
|
||||
public static readonly DependencyProperty IsIndeterminateProperty =
|
||||
DependencyProperty.Register(nameof(IsIndeterminate),
|
||||
typeof(bool), typeof(ProgressRing), new PropertyMetadata(false, OnIsIndeterminatePropertyChanged));
|
||||
|
||||
public static readonly DependencyProperty ThicknessProperty =
|
||||
DependencyProperty.Register(nameof(Thickness),
|
||||
typeof(double), typeof(ProgressRing));
|
||||
|
||||
public static DependencyProperty TemplateSettingsProperty =
|
||||
DependencyProperty.Register(nameof(TemplateSettings),
|
||||
typeof(ProgressRingTemplateSettings), typeof(ProgressRing));
|
||||
|
||||
public ProgressRing()
|
||||
{
|
||||
DefaultStyleKey = typeof(ProgressRing);
|
||||
SetValue(TemplateSettingsProperty, new ProgressRingTemplateSettings());
|
||||
}
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get => (bool)GetValue(IsActiveProperty);
|
||||
set => SetValue(IsActiveProperty, value);
|
||||
}
|
||||
|
||||
public bool IsIndeterminate
|
||||
{
|
||||
get => (bool)GetValue(IsIndeterminateProperty);
|
||||
set => SetValue(IsIndeterminateProperty, value);
|
||||
}
|
||||
|
||||
public double Thickness
|
||||
{
|
||||
get => (double)GetValue(ThicknessProperty);
|
||||
set => SetValue(ThicknessProperty, value);
|
||||
}
|
||||
|
||||
public ProgressRingTemplateSettings TemplateSettings
|
||||
{
|
||||
get => (ProgressRingTemplateSettings)GetValue(TemplateSettingsProperty);
|
||||
set => SetValue(TemplateSettingsProperty, value);
|
||||
}
|
||||
|
||||
public override void OnApplyTemplate()
|
||||
{
|
||||
UpdateValue();
|
||||
UpdateVisualState();
|
||||
}
|
||||
|
||||
protected override void OnValueChanged(double oldValue, double newValue)
|
||||
{
|
||||
UpdateValue();
|
||||
base.OnValueChanged(oldValue, newValue);
|
||||
}
|
||||
|
||||
private void UpdateValue()
|
||||
{
|
||||
TemplateSettings.EndAngle = Value == Maximum ? 359.999 : 359.999 * (Value / (Maximum - Minimum));
|
||||
}
|
||||
|
||||
private static void OnIsActivePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
(dependencyObject as ProgressRing)?.OnIsActivePropertyChanged();
|
||||
}
|
||||
|
||||
private static void OnIsIndeterminatePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
(dependencyObject as ProgressRing)?.OnIsIndeterminatePropertyChanged();
|
||||
}
|
||||
|
||||
private void OnIsActivePropertyChanged()
|
||||
{
|
||||
UpdateVisualState();
|
||||
}
|
||||
|
||||
private void OnIsIndeterminatePropertyChanged()
|
||||
{
|
||||
UpdateVisualState();
|
||||
}
|
||||
|
||||
private void UpdateVisualState()
|
||||
{
|
||||
VisualStateManager.GoToState(this, IsActive ? IsIndeterminate ? "IndeterminateActive" : "Active" : "Inactive", true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:TheXamlGuy.UI.WPF.Controls"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
<SolidColorBrush x:Key="ProgressRingForeground" Color="White" />
|
||||
<SolidColorBrush x:Key="ProgressRingBackground" Color="Transparent" />
|
||||
<system:Double x:Key="ProgressRingStrokeThickness">4</system:Double>
|
||||
<Style TargetType="controls:ProgressRing">
|
||||
<Setter Property="Foreground" Value="{StaticResource ProgressRingForeground}" />
|
||||
<Setter Property="Background" Value="{StaticResource ProgressRingBackground}" />
|
||||
<Setter Property="Thickness" Value="{StaticResource ProgressRingStrokeThickness}" />
|
||||
<Setter Property="IsHitTestVisible" Value="False" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="MinHeight" Value="16" />
|
||||
<Setter Property="MinWidth" Value="16" />
|
||||
<Setter Property="IsTabStop" Value="False" />
|
||||
<Setter Property="Width" Value="32" />
|
||||
<Setter Property="Height" Value="32" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="controls:ProgressRing">
|
||||
<Grid x:Name="LayoutRoot">
|
||||
<Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
|
||||
<controls:Arc
|
||||
Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
EndAngle="359"
|
||||
StartAngle="0"
|
||||
Stroke="{TemplateBinding Background}"
|
||||
StrokeThickness="{TemplateBinding Thickness}" />
|
||||
<controls:Arc
|
||||
x:Name="ForegroundArc"
|
||||
Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
EndAngle="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EndAngle}"
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
StartAngle="0"
|
||||
Stroke="{TemplateBinding Foreground}"
|
||||
StrokeEndLineCap="Round"
|
||||
StrokeStartLineCap="Round"
|
||||
StrokeThickness="{TemplateBinding Thickness}">
|
||||
<controls:Arc.RenderTransform>
|
||||
<TransformGroup>
|
||||
<RotateTransform x:Name="RotateTransform" />
|
||||
</TransformGroup>
|
||||
</controls:Arc.RenderTransform>
|
||||
</controls:Arc>
|
||||
</Grid>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Inactive">
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ForegroundArc"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
Duration="0" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="IndeterminateActive">
|
||||
<Storyboard>
|
||||
<DoubleAnimationUsingKeyFrames
|
||||
RepeatBehavior="Forever"
|
||||
Storyboard.TargetName="ForegroundArc"
|
||||
Storyboard.TargetProperty="EndAngle">
|
||||
<SplineDoubleKeyFrame KeyTime="0" Value="0" />
|
||||
<SplineDoubleKeyFrame KeyTime="0:0:1" Value="179" />
|
||||
<SplineDoubleKeyFrame KeyTime="0:0:2" Value="0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimation
|
||||
RepeatBehavior="Forever"
|
||||
Storyboard.TargetName="RotateTransform"
|
||||
Storyboard.TargetProperty="Angle"
|
||||
From="00"
|
||||
To="359"
|
||||
Duration="0:0:0.65" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Active" />
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace TheXamlGuy.UI.WPF.Controls;
|
||||
|
||||
public class ProgressRingTemplateSettings : DependencyObject
|
||||
{
|
||||
public static readonly DependencyProperty EndAngleProperty =
|
||||
DependencyProperty.Register(nameof(EndAngle),
|
||||
typeof(double), typeof(ProgressRingTemplateSettings));
|
||||
|
||||
public double EndAngle
|
||||
{
|
||||
get => (double)GetValue(EndAngleProperty);
|
||||
set => SetValue(EndAngleProperty, value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user