Eigene Kreis-Verlaufsanzeige als Animation zum Datenladen

Mein BusyControl

Es gibt wohl keine Geschäftsanwendung unter Silverlight, die nicht Daten holt – und durchaus das Problem zu überwinden hat, daß das eben dauert, so gut man’s auch organisiert. Nicht nur, weil der User überhaupt mitbekommen soll, daß gerade was passiert, ist es eigentlich unerläßlich, das irgendwie anzuzeigen, sinnvollerweise als Animation, um zu sagen „es passiert was!“ – und zwar möglichst „schön“, das reduziert psychologisch gesehen die Ungeduld (=Unzufriedenheit) ungemein.

Soweit klar. Nun gibt es ja im Silverlight Toolkit das „ActivityControl“ bzw. „BusyIndicator“. Doch den tatsächlich asynchronen Vorgang des Daten Holens auf diese Weise als synchron zu gestalten, sehe ich als Verlust: der Anwender könnte in dieser Zeit noch etwas tun und das „Warte…“-Gefühl würde sich weniger einstellen. Außerdem finde ich es nicht gerade hübsch…

Nun hab ich ziemlich gesucht, wo ich so ein schönes kreisrundes Verlaufscontrol her bekomme – da ich nicht zuerst Designer bin, sondern Datenbankprogrammierer. Dieses wollte ich z.B. in das DataGrid einblenden, was gerade auf seine Daten wartet. Erst dachte ich es mit einem animated GIF hinzubekommen (Verzeihung, ich sehe es ja schon ein) – das war ein hakliger Flop, da sind wir von Xaml was anderes gewohnt.

So hab ich’s dann doch selbst in Blend gemacht – vielleicht eine Ermutigung für andere, die eher einen Bogen machen, wenn’s um Investition in Design und Animationen geht: es ging sehr einfach und ich bin sehr zufrieden mit dem Ergebnis.

Hier die Schritte, um es selbst hinzubekommen:

1. Projekt in Expression Blend öffnen, neues UserControl anlegen. Dort ins LayoutRoot-Grid ein Control vom Typ „Arc“ (Bogen) einfügen.

2. Diesem Control die Eigenschaften geben EndAngle=“360″, StartAngle=“0″ Width und Height z.B. 50. Dann die Background-Eigenschaft mit einem GradientBrush füllen, mit starkem Farbverlauf (z.B. weiß bis rot).

3. Nun StoryBoard anlegen (im Standard links unten „Objects and Timeline“) und benennen (im Beispiel stbRotate), auf 1,5 Sekunden klicken (um den Zustand nach Verlauf von 1,5 Sek zu definieren), anschließend unter den eigenschaften des Controls unten „Transform“ auswählen, dort „Rotate“ und den Angle auf 360 Grad setzen.

4. Im XAML-Code beim StoryBoard das Objekt DoubleAnimation mit der Eigenschaft RepeatBehaviour=“Forever“ versehen.

Das war’s schon gewesen. Jetzt muß das UserControl nur noch eingebaut werden. Platzieren, wo’s gewünscht ist – ist setze es meist oben links über das betreffende DataGrid, und setze die Visibility standardmäßig erst mal auf „Collapsed“. Jetzt muß ich nur noch beim Aufruf der Datenhol-Methode (z.B. im LoadedData einer DomainDataSource bei Ria-Services oder beim Aufruf der …Async()-Methode bei Standard-WCF-Services) das Control auf Visibility=Visibility.Visible setzen und beim Ankommen der Daten zurück auf Collapsed.

Wer’s nicht selber machen will – hier ist der Sourcecode.
1. XAML:

<UserControl
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" x:Name="userControl"
	mc:Ignorable="d"
	x:Class="Opas1.LoadingAnimation"
	d:DesignWidth="100" d:DesignHeight="100" RenderTransformOrigin="0.5,0.5" >
	<UserControl.Resources>
		<Storyboard x:Name="stbRotate">
			<DoubleAnimation 
                Duration="0:0:1.5" 
                To="360" 
                RepeatBehavior="Forever"
                Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" 
                Storyboard.TargetName="userControl" 
                d:IsOptimized="True"/>
		</Storyboard>
	</UserControl.Resources>
	<UserControl.RenderTransform>
		<CompositeTransform/>
	</UserControl.RenderTransform>
	<UserControl.Background>
		<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
			<GradientStop Color="Black" Offset="0"/>
			<GradientStop Color="White" Offset="1"/>
		</LinearGradientBrush>
	</UserControl.Background>
	
	<Grid >
		<ed:Arc x:Name="Round" ArcThickness="6" 
			Grid.Column="0"
			Grid.Row="0"
			ArcThicknessUnit="Pixel" 
			EndAngle="360" 
			Height="50" 
			Stretch="None" 
			StartAngle="0" 
			Width="50" 
			>
			<ed:Arc.Fill>
				<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
					<GradientStop Color="White" Offset="0"/>
            		<GradientStop Color="#FF950505" Offset="1"/>
				</LinearGradientBrush>
			</ed:Arc.Fill>
		</ed:Arc>
	</Grid>
</UserControl>

2. Und hier der Code:

public partial class LoadingAnimation : UserControl
{
    public LoadingAnimation()
	{
		// Required to initialize variables
		InitializeComponent();
        this.Loaded += new RoutedEventHandler(LoadingAnimation_Loaded);
	}

    void LoadingAnimation_Loaded(object sender, RoutedEventArgs e)
    {
        this.stbRotate.Begin();
    }
}
Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

%d Bloggern gefällt das: