The Architect
aka "DotNetMastermind"

Wissenswertes zur Entwicklung hochwertiger grafischer Oberflächen (Rich User Interfaces) in WPF, Silverlight (dotNet, .NET) und Silverlight for Windows Phone 7 (WP7)
Gloweffekt in .NET 4.0 (BitmapEffect-Klasse)
Seit .NET 4.0 läuft die Zuweisung eines „OuterGlowBitmapEffektes“ ins Leere.

Das Ärgerliche bei dem Versuch diese Klasse zu verwenden ist, dass man im XAML-Code zunächst einmal nichts bemerkt (kein Hinweis im Visual Studio auf eine obsolete [veraltete bzw. ungültig gewordene] Klasse und auch keine Exception beim Ausführen der Applikation (ein Exception-Handling ist im XAML-Code ja nur bedingt möglich). Somit überprüft man erst andere mögliche Fehlerquellen um dann festzustellen, dass sowohl die BitmapEffect-Klasse als auch die OuterGlowBitmapEffect-Klasse weiterhin in .NET 4.0 existent sind, jedoch bei einer Zuweisung der gewünschte Effekt ausbleibt.

Im MSDN habe ich diesbezüglich folgenden Artikel gefunden :
http://msdn.microsoft.com/en-us/library/ms743435.aspx 

Da ich diesen Effekt jedoch für meine WPFSmartButtons benötige, habe ich als Workaround stattdessen die DropShadowEffect-Klasse verwendet, welche von der Effect-Klasse abgeleitet ist.

Statt z.B.
<OuterGlowBitmapEffect GlowColor="White" GlowSize="10" />

habe ich
<DropShadowEffect ShadowDepth="0" Color="White" BlurRadius="30" RenderingBias="Quality"/>

verwendet.

Der Effekt ist nahezu identisch, auch wenn geringfügige optische Abweichungen bestehen.

Screenshots der Beispielapplikation :




Bei Fragen und Anregungen schreibt mir doch einfach einen Kommentar oder eine PN.

Die Beispielapplikation könnt ihr euch hier herunterladen :

  BitmapEffect.zip

kick it on dotnet-kicks.de
Posted: Dez 30 2010, 12:51 von TheArchitect | mit 1 comment(s)
Abgelegt unter: , , , ,
Silverlight Applikation pausieren ohne dass der Browser „einfriert“
Zum Pausieren einer Silverlight Applikation kann man nicht einfach die Methode Thread.Sleep( int millisecondsTimeout ) aus dem Namespace System.Threading verwenden, da dadurch nicht nur die Silverlight Applikation, sondern darüber hinaus auch der ganze Browser (in welchem die Applikation ja als Client ausgeführt wird) einfriert.

Als Workaround habe ich stattdessen ein Storyboard verwendet, welches eine frei bestimmbare Zeit einfach gar nichts macht. Dann habe ich dieses Storyboard in eine Methode verpackt, welche folgendermaßen aussieht :

private void SLThreadSleep( int TimeoutInMilliseconds )
{
    // Storyboard für eine Pause von x Millisekunden erzeugen ...
    Storyboard SleepStoryboard = new Storyboard();
    DoubleAnimation SleepDuration = new DoubleAnimation() { Duration = TimeSpan.FromMilliseconds( TimeoutInMilliseconds ), From = 1, To = 1 };
    SleepStoryboard.Children.Add( SleepDuration );
    Storyboard.SetTarget( SleepDuration, LayoutRoot );
    Storyboard.SetTargetProperty( SleepDuration, new PropertyPath( "(UIElement.Opacity)" ) );
    SleepStoryboard.Completed += new EventHandler( (ds, de) =>
        {
        // Master Grid und gesamten Inhalt wieder aktivieren
        LayoutRoot.IsHitTestVisible = true;
        // Das Rücksetzen des Buttontextes ist nur für die Beispielapplikation gedacht
        btnSleep2.Content = "SL App 5 Sekunden pausieren (mit Storyboard)";
        } );
    SleepStoryboard.Begin();
}


(Bei LayoutRoot handelt es sich um das sogenannte Master-Grid, welches sich im Logical Tree an oberster Stelle befindet)

Bei Fragen und Anregungen schreibt mir doch einfach einen Kommentar oder eine PN.

Die Beispielapplikation könnt ihr euch hier herunterladen :

  Sl4ThreadSleep.zip

kick it on dotnet-kicks.de
Posted: Dez 30 2010, 12:33 von TheArchitect | mit no comments
Abgelegt unter: , ,
TextBlock animiert ein- und ausblenden
Nachdem ich gestern bei einem Film die Einblendungen der „credits“ im Vorspann sah, dachte ich mir : „Das geht doch bestimmt auch ganz einfach mit WPF“.

Habe mich dann auch dran gesetzt und eine kleine Extension-Methode geschrieben, mit welcher man jeden beliebigen TextBlock um eine „credits“-ähnliche Animation erweitern kann. Die Extension-Methode sieht folgendermaßen aus :

public static void AddSmartFadingAnimation( this TextBlock TextBlockToAnimate,
                                            List<string> FadingTextList,
                                            double TextPromptDuration,
                                            double FadingSpeed )

Die Verwendung der Methode ist recht einfach. Man legt einfach ein TextBlock-Control in seiner GUI an, weist dem TextBlock-Control alle gewünschten Eigenschaften (Properties) zu, erstellt ein String-Collection (List<sring>), füllt diese mit den entsprechenden Texten ( .add(„Text“) ) und wendet die (Extension-)Methode AddSmartFadingAnimation(...) auf dem TextBlock-Objekt an. Eine beispielhafte Verwendung der Methode sieht folgendermaßen aus :

List<string> TextList = new List<string>();
for( int i = 0; i < 10; i++ )
  TextList.Add( "Einzublendender Text Nr. " + i );

tblFadingInfo.AddSmartFadingAnimation( TextList, 1000, 1500 );

(tblFadingInfo ist hierbei der Name eines beispielhaften TextBlock-Objektes)


Screenshots der Beispielapplikation :






Bei Fragen und Anregungen schreibt mir doch einfach einen Kommentar oder eine PN.

Die Beispielapplikation könnt ihr euch hier herunterladen :

  SmartTextFading.zip



kick it on dotnet-kicks.de
Silverlight 4 Templates für WP7 Apps
Als Ergänzung zum meinem Blog-Eintrag vom 22.11.2010 (http://dotnet-forum.de/blogs/thearchitect/archive/2010/11/22/windows-phone-7-entwicklung-best-practice.aspx) hier nochmals die Möglichkeit zum Download eines Projektes, welches ein einfaches Template sowie ein erweitertes Template (mit einigen Controls und dem Wechsel zwischen einzelnen Seiten) enthält.

Die Templates wurden bewusst sehr einfach gehalten, um als Vorlage für die weitere Entwicklung zu dienen (es sind also keine Storyboards oder Animationen enthalten).

Screenshots des einfachen Templates ( SL4 - WP7 ) :




Screenshots des erweiterten Templates ( SL4 ) :




Screenshots des erweiterten Templates ( WP7 ) :



Wie man erkennen kann, sind optische Unterschiede kaum noch vorhanden.

Wichtig ist es jedoch die nachfolgenden Unterschiede zwischen der SL4 App und der WP7 App zu beachten.

In der WMAppManifest.xml folgende Änderung vornehmen :

<Tasks>
<DefaultTask  Name ="_default" NavigationPage="Page1.xaml"/>
</Tasks>


Das URI-Mapping muss in die App.xaml verlagert werden und zusätzlich muss folgender Code in den Konstruktor der App.xaml.cs eingefügt werden :

RootFrame.UriMapper = Resources["UriMapper"] as UriMapper;


Bei Fragen und Anregungen schreibt mir doch einfach einen Kommentar oder eine PN.

Das Projekt mit den beiden Templates könnt ihr euch hier herunterladen :

  SL4WP7Templates.zip


  WP7ExtTemplate.zip

kick it on dotnet-kicks.de
Windows Phone 7 Entwicklung “Best Practice“
Bei einer kürzlich durchgeführten Entwicklung einer grafischen Oberfläche (GUI) für eine Windows Phone 7 (WP7) App bin ich folgendermaßen vorgegangen :

Für die Entwicklung einer WP7 App muss man die Windows Phone Developer Tools RTW installieren. Diese sind verfügbar unter:
http://www.microsoft.com/downloads/details.aspx?FamilyID=04704acf-a63a-4f97-952c-8b51b34b00ce&displayLang=de

Die Tools bestehen aus folgenden Komponenten :

•    Visual Studio 2010 Express for Windows Phone
•    Windows Phone Emulator Resources
•    Silverlight 4 Tools für Visual Studio
•    XNA Game Studio 4.0
•    Microsoft Expression Blend for Windows Phone


Dies bedeutet jedoch, dass man auf jeden Fall neben seinem produktiv genutzten Visual Studio noch eine zweite Express-Version installieren müsste. Da die Installation von mehreren Visual Studio Versionen in manchen Fällen (nicht immer!) zu Problemen führen kann, habe ich mir eine virtuelle Maschine eingerichtet, welche als Entwicklungsplattform dienen sollte. Auf diese habe ich dann Windows 7 Professional 32 Bit und die Windows Phone Developer Tools RTW installiert.

Bei ersten Tests fielen mir sofort folgende Nachteile des WP7 Emulators auf :
  • Der Emulator ist nicht gerade der schnellste (ich dachte erst, weil er in der virtuellen Maschine läuft, aber die anderen Programme starten fast genauso schnell wie im Host, also liegt es am Emulator)
  • GUI-Tests mit vielen Texteingaben sind sehr mühselig, da diese immer über die virtuelle Phone Tastatur erfolgen müssen und nicht über die normale Tastatur erfolgen können
Um die WP7 App also effizient entwickeln zu können, musste ich mir etwas einfallen lassen.

So kam es, dass ich in meinem Host (dem produktiven Entwicklungsrechner) eine Silverlight 4 (SL4) Applikation erstellt habe, welche als Grundlage für die WP7 App dienen sollte.

Um die GUI-Identität zu wahren, musste ich zunächst einmal die optischen Vorgaben einer WP7 App in SL4 abbilden. Hierzu mussten einige Vorarbeiten (das Anlegen von Systemressourcen) geleistet werden.

Folgende Eigenschaften muss das “User Control“ Element besitzen, damit eine WP7 App in SL4 nachgebildet werden kann :

<UserControl … Height="768" Width="480" FontFamily="Segoe UI"
FontSize="20" Foreground="White">


Die Größe des Fenster sollte bei einer „normalen“ Phone 7 Applikation eine Breite von 480px und eine Höhe von 768px haben, bei einer sogenannten „Panorama“ Application liegen die Werte bei einer Breite von 480px und einer Höhe von 800px (in diesem Beitrag wird lediglich die „normale“ Applikation besprochen). Die Nachbildung der drei weiteren Systemressourcen erreicht man mit der Zuweisung der Font-Family „Segoe UI“, einer Font-Size von "20" und der Foreground-Farbe „White“.
 
Darüber hinaus musste ich die von jeder WP7 App genutzten Font-Systemressourcen in SL4 verfügbar machen. Also habe ich die Font-Systemressourcen in Form von „Application.Resourcen“ nachgebildet :

<Application.Resources>
<!-- Dies sind Nachbildungen der Standard WP7-Systemressourcen -->
<Style x:Key="PhoneTextNormalStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="20"/>
</Style>

<Style x:Key="PhoneTextTitle1Style" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="72"/>
</Style>

<Style x:Key="PhoneTextTitle2Style" TargetType="TextBlock">
<Setter Property="FontFamily" Value="Segoe UI Light"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="32"/>
</Style>
</Application.Resources>


Somit war es mir möglich, diese Ressourcen den TextBlock-Controls zuzuordnen, ohne diese in WP7 nochmals ändern zu müssen (da dort ja identische Systemressourcen existieren) und dennoch eine identische Optik zu erreichen.

Eine in beiden Entwicklungsumgebungen gültige Zuweisung lautet dann :

<TextBlock x:Name="ApplicationTitle" Text="Name der App"
Style="{StaticResource PhoneTextNormalStyle}"/>


Wie gesagt behält diese Zuweisung ihre Gültigkeit auch in der WP7 Entwicklungsumgebung und damit hält man auch die Microsoft GUI Design Standards für die WP7 App Entwicklung ein, welche das Nutzen dieser Systemressourcen ausdrücklich empfehlen.

Nun konnte ich also die WP7 App in SL4 effizient auf meinem schnellen Produktiv-Rechner entwickeln und nicht gezwungenermaßen auf der doch schon etwas langsamerem virtuellen Maschine mit den oben genannten Nachteilen.

Auf diese Weise war es mir möglich die GUI der nachfolgend dargestellten WP7 App voll funktionsfähig innerhalb von nur 5 (!) Tagen inkl. aller dazugehörigen Funktionalitäten wie Datenbindung, DataTemplates, Überblendeffekten, Storyboards, dynamischer Anzeige, Dual-Language-Support etc. fertig zu stellen.

Screenshots der WP7 App :






Das Silverlight-Pendant sieht folgendermaßen aus :





Wie man sieht, sind die optischen Unterschiede nur noch marginal.

Bei Fragen und Anregungen schreibt mir doch einfach einen Kommentar oder eine PN.

Die Vorlage für eine WP7 App in Form eines Silverlight 4 Projektes könnt ihr hier herunterladen :

  SL4WP7Template.zip

kick it on dotnet-kicks.de