WPF chargement spinner

L’objective est d’afficher les informations sur lesquelles l’application fonctionne. Je recherche donc un exemple d’implémentation intelligent d’un spinner de chargement utilisant WPF / MVVM.

J’ai écrit ce contrôle d’utilisateur qui peut aider, il affichera des messages avec une barre de progression en train de tourner pour montrer qu’il charge actuellement quelque chose.

 

Il possède deux propriétés de base auxquelles vous pouvez vous connecter.

Pour obtenir ceci:

entrer la description de l'image ici

Collez ceci dans un contrôle utilisateur:

                         

Pour obtenir un effet de disparition ColorAnimationUsingKeyFrames sur chaque ellipse, ajoutez ce qui suit après chaque élément ColorAnimationUsingKeyFrames . Assurez-vous de le diriger vers l’ellipse correcte.

                   

Un très simple “plug and play” spinner pourrait être l’une des icons tournantes du package Font Awesome Wpf ( icons Spinning ).

L’utilisation est assez simple, installez simplement le paquet nuget:

 PM> Install-Package FontAwesome.WPF 

Puis ajoutez la référence à l’espace de noms

 xmlns:fa="http://schemas.fontawesome.io/icons/" 

et utilisez le contrôle ImageAwesome. Définissez la propriété Spin = “True” et sélectionnez l’une des icons “Spinner”, “Refresh”, “Cog” et “CircleOutlinedNotched”. Il est évolutif et peut être redimensionné en définissant la largeur et la hauteur.

      

Avec des images

Résumé visuel des options pour les icons tournantes. Enregistré en utilisant Screen To Gif .


Police-Awesome-WPF

Documentation sur GitHub .

Installer via NuGet:

PM> Install-Package FontAwesome.WPF

Ressemble à ça:

XAML:

  

Les icons illustrées sont Spinner , CircleOutlineNotch , Refresh et Cog . Il y en a beaucoup d’autres .


Méthode de @HAdes

XAML copier / coller.

Découvrez le BusyIndicator dans le WPF Toolkit étendu .

Ceci est une mise à jour du code donné par @HAdes pour paramétrer la taille, la hauteur et la taille de l’ellipse.

Cette implémentation devrait automatiquement calculer les angles, les largeurs et les hauteurs requirejs à la volée.

Le contrôle utilisateur est lié à lui-même (code-behind) qui prend en charge tous les calculs.

XAML

                           

Code Behind (C #)

 using System; using System.Windows; using System.Windows.Controls; namespace WpfApplication2 { ///  /// Interaction logic for Spinner.xaml ///  public partial class Spinner : UserControl { public int EllipseSize { get; set; } = 8; public int SpinnerHeight { get; set; } = 0; public int SpinnerWidth { get; set; } = 0; // start positions public EllipseStartPosition EllipseN { get; private set; } public EllipseStartPosition EllipseNE { get; private set; } public EllipseStartPosition EllipseE { get; private set; } public EllipseStartPosition EllipseSE { get; private set; } public EllipseStartPosition EllipseS { get; private set; } public EllipseStartPosition EllipseSW { get; private set; } public EllipseStartPosition EllipseW { get; private set; } public EllipseStartPosition EllipseNW { get; private set; } public Spinner() { InitializeComponent(); } private void initialSetup() { float horizontalCenter = (float)(SpinnerWidth / 2); float verticalCenter = (float)(SpinnerHeight / 2); float distance = (float)Math.Min(SpinnerHeight, SpinnerWidth) /2; double angleInRadians = 44.8; float cosine = (float)Math.Cos(angleInRadians); float sine = (float)Math.Sin(angleInRadians); EllipseN = newPos(left: horizontalCenter, top: verticalCenter - distance); EllipseNE = newPos(left: horizontalCenter + (distance * cosine), top: verticalCenter - (distance * sine)); EllipseE = newPos(left: horizontalCenter + distance, top: verticalCenter); EllipseSE = newPos(left: horizontalCenter + (distance * cosine), top: verticalCenter + (distance * sine)); EllipseS = newPos(left: horizontalCenter, top: verticalCenter + distance); EllipseSW = newPos(left: horizontalCenter - (distance * cosine), top: verticalCenter + (distance * sine)); EllipseW = newPos(left: horizontalCenter - distance, top: verticalCenter); EllipseNW = newPos(left: horizontalCenter - (distance * cosine), top: verticalCenter - (distance * sine)); } private EllipseStartPosition newPos(float left, float top) { return new EllipseStartPosition() { Left = left, Top = top }; } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { if(e.Property.Name == "Height") { SpinnerHeight = Convert.ToInt32(e.NewValue); } if (e.Property.Name == "Width") { SpinnerWidth = Convert.ToInt32(e.NewValue); } if(SpinnerHeight > 0 && SpinnerWidth > 0) { initialSetup(); } base.OnPropertyChanged(e); } } public struct EllipseStartPosition { public float Left { get; set; } public float Top { get; set; } } } 

Utilisation de l’échantillon

      

utilisez un type enum pour indiquer l’état de votre ViewModel

 public enum ViewModeType { Default, Busy //etc. } 

alors dans votre classe de base ViewModels, utilisez une propriété

 public ViewModeType ViewMode { get { return this.viewMode; } set { if (this.viewMode != value) { this.viewMode = value; //You should notify property changed here } } } 

et en vue déclencher le ViewMode et s’il est occupé show

    

Voici un exemple de solution tout en xaml. Il se lie à un booléen “IsWorking” dans la vue pour afficher le contrôle et lancer l’animation.

                      

Dans WPF, vous pouvez maintenant faire simplement:

 Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait; // set the cursor to loading spinner Mouse.OverrideCursor = System.Windows.Input.Cursors.Arrow; // set the cursor back to arrow 

Ce repo sur github semble bien faire le travail:

https://github.com/blackspikeltd/Xaml-Spinners-WPF

Les essoreuses sont légères et peuvent facilement être placées partout où cela est nécessaire. Il y a un exemple de projet inclus dans le repo qui montre comment les utiliser.

Pas de méchant derrière les codes avec beaucoup de logique non plus. Si la prise en charge de MVVM est nécessaire, il suffit de les prendre et de les lancer dans une grid avec une liaison de visibilité.

CircularProgressBarBlue.xaml

              

CircularProgressBarBlue.xaml.cs

en utilisant le système;

en utilisant System.Windows;

en utilisant System.Windows.Media.Animation;

  ///  /// Interaction logic for CircularProgressBarBlue.xaml ///  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 { } } }