Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Use ProgressRing in Windows Phone 8

In referencing http://briandunnington.github.io/progressring-wp8.html for a fun new implementation of a progress indicator, I would like to adapt the ProgressRing control to Windows Phone 8. I am not sure though how exactly to add everything in the MainPage of my application. What I have is as follows

MainPage.xaml

<phone:PhoneApplicationPage.Resources>
    <!-- Default style for Windows.UI.Xaml.Controls.ProgressRing -->
    <Style TargetType="controls:ProgressRing">
        <Setter Property="Foreground" Value="{StaticResource AccentBrush}" />
        <Setter Property="IsHitTestVisible" Value="False" />
        <Setter Property="HorizontalAlignment" Value="Center" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="MinHeight" Value="20" />
        <Setter Property="MinWidth" Value="20" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="controls:ProgressRing">
                    <Border x:Name="ProgressRingRoot" Background="{TemplateBinding Background}"
                BorderThickness="{TemplateBinding BorderThickness}"
                BorderBrush="{TemplateBinding BorderBrush}">
                        <Border.Resources>
                            <Style x:Key="ProgressRingEllipseStyle" TargetType="Ellipse">
                                <Setter Property="Opacity" Value="0" />
                                <Setter Property="HorizontalAlignment" Value="Left" />
                                <Setter Property="VerticalAlignment" Value="Top" />
                            </Style>
                        </Border.Resources>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="SizeStates">
                                <VisualState x:Name="Large">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Duration="0"
                                                            Storyboard.TargetName="SixthCircle"
                                                            Storyboard.TargetProperty="Visibility">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Small" />
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="ActiveStates">
                                <VisualState x:Name="Inactive" />
                                <VisualState x:Name="Active">
                                    <Storyboard RepeatBehavior="Forever">
                                        <ObjectAnimationUsingKeyFrames Duration="0"
                                                            Storyboard.TargetName="Ring"
                                                            Storyboard.TargetProperty="Visibility">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E1"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="0">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E2"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="00:00:00.167">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E3"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="00:00:00.334">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E4"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="00:00:00.501">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E5"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="00:00:00.668">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E6"
                                Storyboard.TargetProperty="Opacity"
                                BeginTime="00:00:00.835">
                                            <DiscreteDoubleKeyFrame KeyTime="0" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21" Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22" Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47" Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E1R"
                                BeginTime="0"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-110" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="10" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="93"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="205" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="357" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="439"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="585" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E2R"
                                BeginTime="00:00:00.167"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-116" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="4" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="87"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="199" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="351" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="433"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="579" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E3R"
                                BeginTime="00:00:00.334"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-122" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="-2" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="81"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="193" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="345" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="427"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="573" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E4R"
                                BeginTime="00:00:00.501"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-128" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="-8" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="187" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="339" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="421"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="567" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E5R"
                                BeginTime="00:00:00.668"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-134" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="-14" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="69"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="181" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="331" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="415"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="561" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames
                                Storyboard.TargetName="E6R"
                                BeginTime="00:00:00.835"
                                Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0" Value="-140" KeySpline="0.13,0.21,0.1,0.7"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433" Value="-20" KeySpline="0.02,0.33,0.38,0.77"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2" Value="63"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617" Value="175" KeySpline="0.57,0.17,0.95,0.75"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017" Value="325" KeySpline="0,0.19,0.07,0.72"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783" Value="409"/>
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217" Value="555" KeySpline="0,0,0.95,0.37"/>
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid x:Name="Ring"
                    Margin="{TemplateBinding Padding}"
                    MaxWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.MaxSideLength}"
                    MaxHeight="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.MaxSideLength}"
                    Visibility="Collapsed"
                    RenderTransformOrigin=".5,.5"
                    FlowDirection="LeftToRight">
                            <Canvas RenderTransformOrigin=".5,.5">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E1R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E1"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                            <Canvas RenderTransformOrigin=".5,.5">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E2R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E2"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                            <Canvas RenderTransformOrigin=".5,.5">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E3R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E3"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                            <Canvas RenderTransformOrigin=".5,.5">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E4R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E4"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                            <Canvas RenderTransformOrigin=".5,.5">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E5R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E5"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                            <Canvas RenderTransformOrigin=".5,.5"
                        Visibility="Collapsed"
                        x:Name="SixthCircle">
                                <Canvas.RenderTransform>
                                    <RotateTransform x:Name="E6R" />
                                </Canvas.RenderTransform>
                                <Ellipse
                        x:Name="E6"
                        Style="{StaticResource ProgressRingEllipseStyle}"
                        Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}"
                        Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}"
                        Fill="{TemplateBinding Foreground}"/>
                            </Canvas>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</phone:PhoneApplicationPage.Resources>

....

//My original progress bar (which I'd like to change to the ProgressRing)
<ProgressBar Name="ProgessBar" 
                        IsIndeterminate="True" 
                        Height="20" Foreground="{StaticResource PhoneAccentBrush}" 
                        Visibility="Collapsed" 
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center"/>

And a class, which I'm not sure where to place or how to reference in the MainPage. Currently I have placed the class in a folder named Common

ProgressRing.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace TestApp.Common
{
public class ProgressRing : Control
{
    bool hasAppliedTemplate = false;

    public ProgressRing()
    {
        this.DefaultStyleKey = typeof(ProgressRing);
        TemplateSettings = new TemplateSettingValues(60);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        hasAppliedTemplate = true;
        UpdateState(this.IsActive);
    }

    void UpdateState(bool isActive)
    {
        if (hasAppliedTemplate)
        {
            string state = isActive ? "Active" : "Inactive";
            System.Windows.VisualStateManager.GoToState(this, state, true);
        }
    }

    protected override System.Windows.Size MeasureOverride(System.Windows.Size availableSize)
    {
        var width = 100D;
        if(!System.ComponentModel.DesignerProperties.IsInDesignTool)
            width = this.Width != double.NaN ? this.Width : availableSize.Width;
        TemplateSettings = new TemplateSettingValues(width);
        return base.MeasureOverride(availableSize);
    }

    public bool IsActive
    {
        get { return (bool)GetValue(IsActiveProperty); }
        set { SetValue(IsActiveProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsActive.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsActiveProperty =
        DependencyProperty.Register("IsActive", typeof(bool), typeof(ProgressRing), new PropertyMetadata(false, new PropertyChangedCallback(IsActiveChanged)));

    private static void IsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        var pr = (ProgressRing) d;
        var isActive = (bool)args.NewValue;
        pr.UpdateState(isActive);
    }

    public TemplateSettingValues TemplateSettings
    {
        get { return (TemplateSettingValues)GetValue(TemplateSettingsProperty); }
        set { SetValue(TemplateSettingsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for TemplateSettings.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TemplateSettingsProperty =
        DependencyProperty.Register("TemplateSettings", typeof(TemplateSettingValues), typeof(ProgressRing), new PropertyMetadata(new TemplateSettingValues(100)));


    public class TemplateSettingValues : System.Windows.DependencyObject
    {
        public TemplateSettingValues(double width)
        {
            MaxSideLength = 400;
            EllipseDiameter = width/10;
            EllipseOffset = new System.Windows.Thickness(EllipseDiameter);
        }

        public double MaxSideLength
        {
            get { return (double)GetValue(MaxSideLengthProperty); }
            set { SetValue(MaxSideLengthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MaxSideLength.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaxSideLengthProperty =
            DependencyProperty.Register("MaxSideLength", typeof(double), typeof(TemplateSettingValues), new PropertyMetadata(0D));

        public double EllipseDiameter
        {
            get { return (double)GetValue(EllipseDiameterProperty); }
            set { SetValue(EllipseDiameterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for EllipseDiameter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty EllipseDiameterProperty =
            DependencyProperty.Register("EllipseDiameter", typeof(double), typeof(TemplateSettingValues), new PropertyMetadata(0D));

        public Thickness EllipseOffset
        {
            get { return (Thickness)GetValue(EllipseOffsetProperty); }
            set { SetValue(EllipseOffsetProperty, value); }
        }

        // Using a DependencyProperty as the backing store for EllipseOffset.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty EllipseOffsetProperty =
            DependencyProperty.Register("EllipseOffset", typeof(Thickness), typeof(TemplateSettingValues), new PropertyMetadata(new Thickness()));
    }
}

}

To note, with what I have above I am getting errors on lines

<Style TargetType="common:ProgressRing"> 

and

<ControlTemplate TargetType="controls:ProgressRing">
like image 851
Matthew Avatar asked Oct 21 '22 23:10

Matthew


1 Answers

You need to write correct XAML namespace:

xmlns:common="clr-namespace:TestApp.Common"

And you need to correct the two lines from

controls:ProgressRing

To

common:ProgressRing

You also need to declare a brush before the style itself:

Or just change the reference to AccentBrush to PhoneAccentBrush.

You must specify Width and if you don't set IsActive to true, it won't show at all. You can use that property for binding visibility :)

<common:ProgressRing Width="50"
                         IsActive="True"/>

Enjoy.

like image 197
Toni Petrina Avatar answered Nov 01 '22 15:11

Toni Petrina