WPF 加载图标

87

目标是显示应用程序正在工作的信息。因此,我正在寻找一种智能的实现示例,使用 WPF / MVVM 来创建一个加载旋转器。

14个回答

1

@Menol发布的自定义Spinner存在一个小问题,即Spinner会向下和向右移动一个点的大小。我已经更新了代码,以便通过减去一半的点来补偿这个偏移量。

以下是更新后的代码:

    private void initialSetup()
    {
        float horizontalCenter = (float)(SpinnerWidth / 2);
        float verticalCenter = (float)(SpinnerHeight / 2);
        float distance = (float)Math.Min(SpinnerHeight, SpinnerWidth) / 2;
        float dotComp = (float)(EllipseSize / 2);

        double angleInRadians = 44.8;
        float cosine = (float)Math.Cos(angleInRadians);
        float sine = (float)Math.Sin(angleInRadians);

        EllipseN = newPos(left: horizontalCenter - dotComp, top: verticalCenter - distance - dotComp);
        EllipseNE = newPos(left: horizontalCenter + (distance * cosine) - dotComp, top: verticalCenter - (distance * sine) - dotComp);
        EllipseE = newPos(left: horizontalCenter + distance - dotComp, top: verticalCenter - dotComp);
        EllipseSE = newPos(left: horizontalCenter + (distance * cosine) - dotComp, top: verticalCenter + (distance * sine) - dotComp);
        EllipseS = newPos(left: horizontalCenter - dotComp, top: verticalCenter + distance - dotComp);
        EllipseSW = newPos(left: horizontalCenter - (distance * cosine) - dotComp, top: verticalCenter + (distance * sine) - dotComp);
        EllipseW = newPos(left: horizontalCenter - distance - dotComp, top: verticalCenter - dotComp);
        EllipseNW = newPos(left: horizontalCenter - (distance * cosine) - dotComp, top: verticalCenter - (distance * sine) - dotComp);
    }

0

CircularProgressBarBlue.xaml

<UserControl 
x:Class="CircularProgressBarBlue"   
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent"
Name="progressBar">
<UserControl.Resources>
    <Storyboard x:Key="spinning" >
        <DoubleAnimation 
            Storyboard.TargetName="SpinnerRotate" 
            Storyboard.TargetProperty="(RotateTransform.Angle)"                 
            From="0" 
            To="360"                 
            RepeatBehavior="Forever"/>
    </Storyboard>
</UserControl.Resources>
<Grid 
    x:Name="LayoutRoot" 
    Background="Transparent" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center">
    <Image Source="C:\SpinnerImage\BlueSpinner.png" RenderTransformOrigin="0.5,0.5" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
        <Image.RenderTransform>
            <RotateTransform 
                x:Name="SpinnerRotate"
                Angle="0"/>
        </Image.RenderTransform>
    </Image>


</Grid>

CircularProgressBarBlue.xaml.cs

using System;

using System.Windows;

using System.Windows.Media.Animation;


        /// <summary>
    /// Interaction logic for CircularProgressBarBlue.xaml
    /// </summary>
    public partial class CircularProgressBarBlue
    {
        private Storyboard _sb;

        public CircularProgressBarBlue()
        {
            InitializeComponent();
            StartStoryBoard();
            IsVisibleChanged += CircularProgressBarBlueIsVisibleChanged;
        }

        void CircularProgressBarBlueIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (_sb == null) return;
            if (e != null && e.NewValue != null && (((bool)e.NewValue)))
            {
                _sb.Begin();
                _sb.Resume();
            }
            else
            {
                _sb.Stop();
            }
        }

        void StartStoryBoard()
        {
            try
            {
                _sb = (Storyboard)TryFindResource("spinning");
                if (_sb != null)
                    _sb.Begin();
            }
            catch
            { }
        }
    }

0
<Grid Width="100" Height="100">
<Ellipse Width="20" Height="20" Stroke="Gray" StrokeThickness="4">
    <Ellipse.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="rotateTransform"
                        Storyboard.TargetProperty="Angle"
                        From="0" To="360"
                        Duration="0:0:1"
                        RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Ellipse.Triggers>
    <Ellipse.RenderTransform>
        <RotateTransform x:Name="rotateTransform" CenterX="10" CenterY="10"/>
    </Ellipse.RenderTransform>
</Ellipse>

在此示例中,使用描边为“灰色”和描边厚度为“4”的椭圆来创建环形。使用RenderTransform属性使用RotateTransform对象旋转椭圆,并通过FrameworkElement的Loaded事件触发动画。DoubleAnimation的持续时间设置为“0:0:1”,表示旋转将需要1秒钟才能完成。RepeatBehavior设置为“Forever”,因此动画将无限重复。
其他正方形形状的旋转器:
<Grid Width="100" Height="100">
<Path Stroke="Gray" StrokeThickness="4" StrokeEndLineCap="Round">
    <Path.Data>
        <PathGeometry>
            <PathFigure StartPoint="50,10">
                <LineSegment Point="10,50" />
                <LineSegment Point="50,90" />
                <LineSegment Point="90,50" />
                <LineSegment Point="50,10" />
            </PathFigure>
        </PathGeometry>
    </Path.Data>
    <Path.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation
                        Storyboard.TargetName="rotateTransform"
                        Storyboard.TargetProperty="Angle"
                        From="0" To="360"
                        Duration="0:0:1"
                        RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Path.Triggers>
    <Path.RenderTransform>
        <RotateTransform x:Name="rotateTransform" CenterX="50" CenterY="50" />
    </Path.RenderTransform>
</Path>

Pic


0

使用应用于几何图形的动画技术,将所需的几何图形添加到路径(Path)中,并对其旋转变换(RotateTransform)进行0-360°的动画处理。

我的Spinner支持两种类型的Spinner:

  1. 圆形:
  2. 环形:

而中心逻辑看起来像这样:

if(spinner.SpinnerType == SpinnerType.Ring)
{
 double innerRad = spinner.Radius - spinner.ItemRadius;
 Point center = new Point(0, 0);
 grp.Children.Add(new EllipseGeometry( center, spinner.Radius, spinner.Radius));
 grp.Children.Add(new EllipseGeometry(center, innerRad, innerRad));                
 return;
}
var points = GetPointsOnCircle( spinner.Diameter/ 2);
double r = spinner.ItemRadius;
foreach (var point in points)
{
 grp.Children.Add(new EllipseGeometry(point, r, r));
 r -= spinner.ContinuousSizeReduction;
}

使用方法如下:

<local:SpinnerControl Diameter="60" Fill="#FFE8B311"/>

这里是源代码!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接