Dans l’article précédent nous avions vu comment réaliser un indicateur de chargement simple. Nous allons aujourd’hui aller plus loin et ajouter une barre de chargement.
Le loader avancé
Je vais maintenant vous présenter un loader avancé qui contient notamment une barre de progression.
Tout d’abord, j’ai créé une nouvelle interface qui sera implémentée par le ViewModel de notre vue :
public interface IAdvancedLoader
{
bool IsLoading { get; }
void StartLoading();
void StopLoading();
void UpdateText(string text);
void UpdateProgress(int progress);
}
On peut voir l’apparition d’une nouvelle méthode, UpdateProgress (int progress), qui permet de mettre à jour la valeur d’avancement pendant que l’affichage du loader.
Voila maintenant le MainViewModel qui implémente cette interface :
public class MainViewModel : ViewModelBase, IAdvancedLoader
{
public DelegateCommand LoadCommand { get; set; }
public MainViewModel()
{
LoadCommand = new DelegateCommand(onLoad);
}
private void onLoad()
{
// ...
}
#region IAdvancedLoader
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
private set { _isLoading = value; Notify(); }
}
private string _textToDisplay;
public string TextToDisplay
{
get { return _textToDisplay; }
set { _textToDisplay = value; Notify(); }
}
private int _progress;
public int Progress
{
get { return _progress; }
set { _progress = value; Notify(); }
}
public void StartLoading()
{
IsLoading = true;
}
public void StopLoading()
{
IsLoading = false;
}
public void UpdateText(string text)
{
TextToDisplay = text;
}
public void UpdateProgress(int progress)
{
Progress = progress;
}
#endregion
}
On peut voir la présence des propriétés IsLoading et TextToDisplay qui ont la même fonction que dans le précédent loader. En plus de cela nous avons une propriété Progress qui va nous servir dans la vue pour afficher la barre de progression. Dans notre exemple, cette valeur de progression doit avoir une valeur entre 0 et 100.
La vue
J’ai modifié un peu le fichier App. xaml :
<Application x:Class="AdvancedLoader.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:View="clr-namespace:AdvancedLoader.View"
xmlns:ViewModel="clr-namespace:AdvancedLoader.ViewModel"
StartupUri="MainWindow.xaml">
<Application.Resources>
<DataTemplate DataType="{x:Type ViewModel:MainViewModel}">
<Grid>
<View:MainView />
<View:AdvancedLoader />
</Grid>
</DataTemplate>
</Application.Resources>
</Application>
Le DataTemplate de notre ViewModel contient maintenant la MainView et l’AdvancedLoader. Voilà le Xaml de AdvanceLoader :
<UserControl x:Class="AdvancedLoader.View.AdvancedLoader"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</UserControl.Resources>
<Border Background="#80000000" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}">
<Border Background="White" VerticalAlignment="Center">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="30" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="1" Text="Please wait" HorizontalAlignment="Center" FontSize="30" FontWeight="Thin" />
<TextBlock Grid.Row="2" Text="{Binding TextToDisplay}" HorizontalAlignment="Center" />
<ProgressBar Grid.Row="4"
Minimum="0"
Value="{Binding Progress}"
Maximum="100"
Height="4"
Margin="0,0,0,-1"
BorderThickness="0"
Foreground="#FF5080C0"
Background="Transparent"
SnapsToDevicePixels="True" />
</Grid>
</Border>
</Border>
</UserControl>
On voit que cette vue est composée d’un border qui prend tout la place, toujours pour afficher un fond gris transparent par dessus toute notre application. Ensuite ce border est composé d’un autre border plus petit, séparer en trois parties (avec une grille). Deux TextBlock sont présent pour afficher respectivement un texte affiché en gros et un texte affiché en plus petit. Le dernier élément constitue notre bar de progression. Les valeurs minimum et maximum de la ProgressBar sont placé à 0 et 100, c’est pour cela que la valeur de Progress dans le MainViewModel doit être comprise en 0 et 100.
La résultat
Afin de pouvoir tester tout cela, il ne nous reste plus qu’à remplir le contenu de OnLoad du MainViewModel :
private void onLoad()
{
Task.Factory.StartNew(() =>
{
StartLoading();
for (int i = 0; i < 100; ++i)
{
UpdateText(string.Format("{0}% downloaded", i));
UpdateProgress(i);
Thread.Sleep(300);
}
StopLoading();
});
}
Voila le résultat :