Daily-Hour 40: Grundlagen der Datenbindung Teil 1

26. März 2010 juergen79 Keine Kommentare

Bevor man überhaupt verwendet, sollte man sich der “statischen” Darstellung der Daten bewusst sein. Deshalb kommt erstmal eine kurze Einführung in die Darstellung von Daten ohne Datenbindung. Hierbei werden die Daten einmal eingelesen und ausgegeben. Auch hier fließt zumindest Daten vom Objekt zur Oberfläche und von der Oberfläche auch wieder zurück. Wenn man keine Datenbindung verwendet, muss man auf Push und Pull ausweichen.

Hierfür betrachten man die einzelnen Datenobjekte der Instanz von der Klasse Person:

public class Person
{
    public string ID { get; }
    public string ReisepassNr {set; get; }
    public string Vorname { set; get; }
    public string Name { set; get; }
    public string DateTime { set; get; }
}

Bei der Speicherung einer Person in einer Datenbank erfolgt mit einem Primärschlüssel, der von der Datenbank automatisch beim Anlegen der Person erzeugt wird. Der Primärschlüssel ist nach der Erzeugung auch nicht mehr veränderbar, deshalb ist ID auch schreibgeschützt.

Die Oberfläche erlaubt das Anzeigen der Eigenschaften (und ändern der veränderlichen Eigenschaften). Für die unveränderlichen Daten verwenden wir zur Darstellung TextBlock und für die veränderlichen TextBox. Da die Elemente auch ansprechen muss, muss man ihnen auch einen Namen zu weisen.

<TextBlock x:Name=”tbID” Text=”ID”/>
<TextBox x:Name=”txVorname” Margin=”2″/>
<TextBox x:Name=”txName” Margin=”2″/>
<TextBox x:Name=”txDate” Margin=”2″/>

Aktionen, die durchgeführt werden sollten:

  • Lesen
  • Speichern
  • Neuanlegen von Daten

Alle Vorgänge werden nur innerhalb des Objektes simuliert und dafür kann man sich 3 Button im XAML-Code anlegen.

Pull-/Push-Beziehung zwischen Objekte und Benutzeroberfläche 
Das Realisieren der Pull-/Push-Beziehung ist realtiv simple. Ein Objekt erhält Daten und ein Eventhandler übergibt Änderungen an das Objekt (oder mehrere). Einen guten Kandiaten für einen Ereignisauslöser findet man in der TextBox (sowie auch in anderen Steuerelementen). Typische Ereignisse auf die man zurückgreifen kann, sind Änderungen des Textes (TextChanged) oder Verlust des Focus (LostFocus). Eine weitere Möglichkeit ist es, den Anwender bestimmen zu lassen, wann das “Ereignis” ausgelöst wird, durch das Drücken einer Schaltfläche.

Den Event-Handler kann man entweder im Code-beside oder im XAML-Code setzen. In der Klasse Person werden wir den Code für das Laden und Speichern von Daten simulieren:

public static Person GetPerson()
{
   return new Person()
   {
        id = 1, Vorname=”Anna”, Name=”Bolika”, Geburtsdatum=new DateTime(1982, 3, 23)
   }
  
}
public void Save()
{
}

Weiters schreiben wir den Code für das laden und anzeigen von Daten:

private void OnLoadClick(object sender, RoutedEventArgs e)
{
    Person p = Person.GetPerson();
    tbID.Text = p.ID.ToString();
    txVorname.Text = p.Vorname;
    txName.Text = p.Name;
    txDate.Text = p.Date.ToShortDateString();
}
private void OnSaveClick(object sender, RoutedEventArgs e)
{
    Person p = new Person();
    p.Vorname  = txVorname.Text;
    p.Name = tx.Name.Text;
    if (txDate.SelectedDate != null))
    {
               p.Date  = (DateTime)txDate.Selected
    } 
}

Installieren von Silverlight Applikationen ohne Browser

26. März 2010 juergen79 Keine Kommentare

Ab Silverlight 4 ist es möglich, Out-of-Browser Applikationen ohne den Browser zu installieren. Wie man es macht zeigt Tim Heuer in seinem Blogeintrag “Installing Silverlight applications without the browser involved

New Silverlight Application Themes

12. März 2010 juergen79 Keine Kommentare

Tim Heuer wurde in seinem Post “SNEAK PEEK: New Silverlight application theme” sogar etwas poetisch, aber es geht im Endeffekt, um die Vorstellung der neuen Themes des UX design team für Silverlight.

Als erstes Codename “Grayscale” etwas an die bestehenden Themes angelehnt, aber doch doch entfernt von den “Traditionelen”:

Codename “Windows Theme” angelehnt an das Windows 7 Design:
Codename “Metro” angelehnt an Zune Desktop (und Geräte) Softwaredesign:

Das war der Ausblick auf einige Silverlight Application Themes. Was wird wirklich erscheinen?

Daily-Hour 39: VisualStateManager VisualTransition

10. März 2010 juergen79 Keine Kommentare

Ein Control-Element wie zB. ein Button können verschiedene Zustände ahben, die auch grafisch angzeigt werden sollten. Ein Standard-Button reagiert auf MouseOver, Normal oder Pressed. Genau jetzt kommt der VisualStateManager zu tragen, der sich im System.Windwos befindet und mit einem abkürzenden Präfix wie zB: vsm (xmlns:vsm=”clr-namespace:System.Windows;assembly=System.Windows”) eingebunden.

Jedes Control besitzt spezifische Zustände (VisualState), die wiederum Zustandsgruppen (VisualStateGroup) angehören. Wenn man diese VisualState kennt, könnnen diese via VisualStateManager definiert werden.

Ein Button enthält folgende Zustände und Gruppen:

CommonStates Normal Mauszeiger befindet sich außerhalb des Controls
CommonStates MouseOver Mauszeiger ist über dem Control
CommonStats Pressed Linke Maustaste wurde gedrückt, während der Mauszeiger über dem Control ist
CommonStates Disable Das Control wurde disabled
FocusState Unfocused Control besitzt nicht den Fokus
FocusState Focused Control besitzt den Fokus

Für den Button gibt es sechs VisualStates in zwei VisualStatesGroups. Mit dem VisualStateManager kann jedem dieser VisualStates ein StoryBoard zugewiesen werden, das eine oder mehrere Animationen enthalten können, so kann ein Zustand überblendet werden. Ein Storyboard kann wie üblich definiert werden.

Die Definition des VisualStateManager erfolgt innerhalb des Controls, wie folgt:

<vsm:VisualStateManager.VisualStateGroups>
    <vsm:VisualStateGroups>
        <vsm:VisualState x:Name=”Normal”>
             <Storyboard>
                …
             </Storyboard>
        </vsm:VisualState>
        <vsm:VisualState x:Name=”MouseOver”>
             <Storyboard>
                …
             </Storyboard>
        </vsm:VisualState>
        …
    </vsm:VisualStateGroups>
</vsm:VisualStateManager.VisualStateGroups>

Diese Deklaration ist nur beispielshaft für Normal und MouseOver und kann beliebig erweitert werden und man kann dementsprechenden die Animationen im Storyboard definieren.

VisualTransition
Man kann weitgehende Kontrolle über die ablaufenden Animationen mittels VisualTransition erlangen. Die VisualTransitions werden in der TransitionsCollection gesammelt, die ein Parameter der VisualStateGroup ist. Eine Transition ist nur innerhalb einer Gruppe möglich, da die Zustände zusammengehörig sind.

Man kann über VisualTransitions definieren:

  • von welchen in welchen Zustand die Transition erfolgen soll (From, To)
  • wie lange der Zustandsübergang dauern soll (GenerateDuration)
  • ob ein Storybord gestartet wird, wenn die Zustandsänderung eintritt (Storyboard)

So kann man die Zustandsübergang von Einem zum Anderem Zustand definieren (zB Pressed nach MouseOver in 2 Sekunden)

<vsm:VisualStateManager.VisualStateGroups>
    <vsm:VisualStateGroups>
        <vsm:VisualStateGroups.Transitions>
             <vsm:VisualTransition From=”Pressed” To=”MouseOver” GeneratedDuration=”0:0:2″/>

        </vsm:VisualStateGroups.Transitions>
        ….
    </vsm:VisualStateGroups>
</vsm:VisualStateManager.VisualStateGroups>

Aber man kann auch ein Storyboard definieren, das während der angegebenen Dauer abgespielt wird.

             <vsm:VisualTransition From=”Pressed” To=”MouseOver” GeneratedDuration=”0:0:2″>
                 <Storyboard>
 
                        <DoubleAnimation Storyboard.TargetName=”EinObjekt” Storyboard.TargetPorperty=”EineProperty”/>
                 </Storyboard>
             </vsm:VisualTransition>

Die bekannten Parameter von Storyboards und Animationen können bei VisualTransitions sowie VisualStates zum Einsatz kommen, wie zB AutoReverse und RepeatBehavior.

Daily-Hour 38: TemplateBinding

6. März 2010 juergen79 Keine Kommentare

Aber ein ControlTemplate muss nicht immer statisch sein, denn man möchte ein Template wieder verwenden können und auch verändern. Über TemplateBinding ist eine Dynamisierung des Templates möglich. Mit der Erweiterung von XAML und der Reaktion des XAML-Parser wird die Angabe nicht als statischen XAML-Text behandelt.

Dabei werden Parameter bei der Deklaration eines Controls angegeben werden, welche innerhalb des Templates verwendet werden, in dem über TemplateBinding auf deren Name verwiesen werden.

<Canvas.Resources>
    <Style x:Key=”TemplateStyle” TargetType=”Button”>
         <Setter Property=”Template”>
             <Setter.Value>
                  <ControlTemplate TargetType=”Button”>
                       <Grid>
                           <Ellipse Width=”{TemplateBinding Width}” Height=”{TemplateBinding Height}”>
                               <Ellipse.Fill>
                               <RadialGradientBrush GradientOrigin=”.3,.6″ Center=”.5,.5″>
                                   <GradientStop Color=”DarkBlue” Offset=”0″/>
                                   <GradientStop Color=”Blue” Offset=”2″/>
                               </RadialGradientBrush>
                               </Ellipse.Fill>
                           </Ellipse>
                           <TextBlock Text=”Button” FontFamily=”Verdana” FontSize=”14″
                                  Foreground=”{TemplateBinding Foreground}”
                                  VerticalAlignment=”Center” HorizontalAlignment=”Center”/>
                       </Grid>
                  </ControlTemplate>
             </Setter.Value>
         </Setter>
    </Style>
</Canvas.Resources>

Über TemplateBinding werden nun die beim Button definierten Parameter Width und Height der Ellipse zugewiesen und die Textfarbe wird mit der Eigenschaft Foreground dem TextBlock zugewiesen. Es können jedoch nur Parameter benützt werden, die für den jeweiligen TargetType gültig sind.

Daily-Hour 37: Customized Controls

5. März 2010 juergen79 Keine Kommentare

Wie man Control-Elemente und Styles definiert und anpasst wurde bisher schon besprochen. Mit Styles können diverse Eigenschaften für andere Control-Elemente übernommen werden. Aber man kann auch weitere Anpassungen im ControlTemplate vornehmen. Hier kann man jedes Control grafisch anpassen, das geht über die üblichen definierbaren Eigenschaften hinaus.

Mit dem ControlTemplate kann man das Control komplett neu- bzw. umgestalten. Man kann die Form ändern oder weitere Controls hinzufügen. Außerdem könnte auch Benutzerinteraktionen festlegen, wie zB MouseEnter-Event. Die spezifischen Methoden des Controls bleiben weiterhin erhalten.

Deklaration von ControlTemplate
Es gibt mehrere Möglichkeiten wie man ControlTemplates defnieren könnte, die sinnvollste ist als Ressource, weil man diese mehrmals wiederverwenden kann:

<Canvas …>
    <Canvas.Resource>
         <ControlTemplate x:Key=”ButtonTemplate” TargetType=”Button”>
              …
         </ControlTemplate>
    </Canvas.Resource>
    <Button Content=”OK” Template=”{StaticResource ButtonTemplate}”/>
</Canvas>

Aufbau von ControlTemplates
Ein ControlTemplate ist nichts anderes als ein in XAML definierter Code in dem mehrere Elemente zusammengesetzt werden. Es muss immer ein RootElement (vom Typ FrameworkElement) haben, das weitere Elemente enthalten kann. Für das gewünschte Control ein eigener “visueller Baum” aufgebaut. Hier werden die Einzelheiten des Controls sowie dessen Parameter wie in XAML üblich festgelegt.

<Canvas Background=”White”>
<Canvas.Resources>
     <Style x:Key=”StyleTemplate” TargetType=”Button”>
          <Setter Property=”Template”>
              <Setter.Value>
                   <ControlTemplate TargetType=”Button”>
                       <Grid>
                           <Ellipse Width=”150″ Height=”100″>
                               <Ellipse.Fill>
                                   <RadialGradientBrush GradientOrigin=”.4,.6″ Center=”.2,.4″>
                                       <GradientStop Color=”DarkBlue” Offset=”0″/>
                                       <GradientStop Color=”Blue” Offset=”2″/>
                                   </RadialGradientBrush>                               
                               </Ellipse.Fill>
                           </Ellipse>
                           <TextBlock Text=”Button” FontFamily=”Verdana” FontSize=”14″ Foreground=”White”
                                 VerticalAlignment=”Center” Horizontal=”Center”/>
                       </Grid>
                   </ControlTemplate>
              </Setter.Value>
          </Setter Property=”Template”>
     </Style>
</Canvas.Resources>
<Button x:Name=”TestButton” Style=”{StaticResource StyleTemplate}” Margin=”10″ Click=”Click_TestButton”/>

</Canvas>

Jetzt wurde ein dem Button ein Style zugewiesen, der ein ControlTemplate definiert. Für den Button wird eine Ellipse mit Farbverlauf sowie einen TextBlock zur Anzeige von Text. Der Button-Deklaration wird ebenso ein Click-Ereignis zugewiesen. Es ist identisch mit der Vorangehensweise bei normalen Buttons.

Daily-Hour 36: Styles

4. März 2010 juergen79 Keine Kommentare

Ein wichtiger Punkt in Silverlight sind sicher das Styling von Applikationen, aber man will nicht jedesmal alles neu definieren sondern auch wiederverwenden.

Der Aufbau von XAML-Dokumenten ist sehr unfangreich und die Zuweisung von Attributen an einzelne Elementen sehr langwierig. Deshalb wünscht man sich Vereinfachungen, für Elemente die gleich aussehen soll. In Silverlight funktioniert das mit Styles, welche als Ressource zugewiesen. Wo der Style definiert werden soll, bleibt dem Entwickler überlassen und ist vom Anwendungsfall abhängig. Man könnte Styles an jeder beliebigen Stelle in der XAML-Struktur definiert werden, je höher dies geschieht, desto sinnvoller ist es. Die Zuweisung wird meistens in der Regel bei Bereichselementen oder im UserControl durchgeführt.

Es  besteht auch die Möglichkeit, die Ressource als Application.Resoure in der App.xaml zu definieren, dann kann man die Style-Definiation in der gesamten Applikation verweden. Für alle Definitionen gilt, es muss innerhalb einer Ressource gemacht werden. Die Definition eines Styles bedarf generell 2 Schritte:

  1. Definieren des Styles
  2. Zuweisung des Styles

Style-Definition
Ein Style wird immer nach folgt aufgebaut:

<Object.Resource>
    <Style …>
        <!– Setter für den Style>
   
</Style>
    <!– Weitere Styles–>
</Object.Resource>

Man kann inner halb der Ressource beliebig viele Style-Blöcke definieren. Ein jeder Style-Block besteht aus dem Style-Tag sowie die zwei Attributen:
    <Style TargetTyp=”TextBlock” x:Key=”TextBlockBlue_12px”>

        <!– Setter für den Style–>

    </Style>

Über TargetTyp wird festgelegt, für welchen Control-Typ der Style definiert ist. Der Style kann nur Controls diesen Typs zugewiesen werden. Mit x:Key wird ein eindeutiger Name des Style zugewiesen, damit der Style später auch einem Control zugewiesen werden kann.

Innerhalb des Style-Tags können verschiedenste Setter definiert werden. Die Setter sind die Definition für den Stil und wird wie folgt aufgebaut:
   

        <Setter Property=”Attribut”>
              <Stetter.Value>
                  <!– Wert –>
              </Stetter.Value>
        </Setter>

Property verweist immer auf die Eigenschaft eines Elementes, diese muss jedoch immer auf die entsprechende Eigenschaft des im TargetTyp definierten Elements sein. In Silverlight ist nur die explizite Zuweisung eines bestimmten Control-Typs durchgeführt werden.

Beispiel:

<UserControl x:Class=”SilverlightApp1.Page” …>
    <UserControl.Resources>
        <Style TargetTyp=”TextBlock” x:Key=”TxtBlockStyle”>
            <Setter Property=”Foreground” Value=”Blue”/>
        </Style>
    </UserControl.Resources>
</UserControl>

Um weitere Eigenschaften eines Styles zu definieren, setzt man weitere Setter innerhalb des Style-Tag. Sollte ein Value aus mehreren Werten bestehen, so werden diese per Element-Schreibweise definiert:

       <Setter Property=”Background”>
            <Setter.Value>
                   <LinearGradientBrush StartPoint=”0.0″ EndPoint=”0.1″>
                         <GradientStop Color=”Blue” Offset=”0″/>
                         <GradientStop Color=”White” Offset=“1.4″/>
                   </LinearGradientBrush>
           <Setter.Value>
       </Setter>

Der Background wird definiert, so wie er es auch ohne Style definiert worden wäre.

Style-Zuweisung

Der definierte Style sollte auch verwendet werden und deshalb muss das Control dem in TargetType angegebenen Typ entsprechen, dann kann der Style durch { und } dem Control-Element zugewiesen werden. Der Parameter StaticResource wird zwingend benötitgt, um den Parser mitzuteilen, dass der XAML-Wert aus einer definierten Ressource ausgewertet werden soll.

<TextBlock Style=”{StaticResource TxtBlockStyle} Text=”irgendein Text”/>

Man kann aber auch durch Style definierte Eigenschaften überschreiben, in dem man einfach die jeweilige Eigenschaft beim Element direkt neu definiert. Die direkt zugewiesenen Parameter haben immer die höhere Priorität.

Der Einsatz von Styles kann jede Menge Zeit ersparen, besonders wenn er über App.xaml für die gesamte Applikation zur Verfügung stehen soll.

Daily-Hour 35: Steuerelement Teil 10: ProgressBar

25. Februar 2010 juergen79 Keine Kommentare

Im Internet tauchen häufig Fortschrittsanzeigen auf, bei Downloads oder sonstigen Anwendungen, wie Installationsroutinen. Der ProgressBar dient, wie wir schon in einen vorigen Eintrag erwähnt, zeigt er Fortschritte an (englisch  Progress). Standardmäßig wird es mit einem Balken, der mit einer Frage gefüllt wird. Der User weiß, das ein ungefüllter Balken 0 % und ein gefüllter Balken 100% darstellt. Wobei letzters den Abschluss der Aktion.

Der ProgressBar ist ein Control, das in Silverlight zur Verfügung gestellt wird, um den Entwickler eine einfache Möglichkeit zu bieten, dies effizient abzubilden. Die Größe des des ProgressBar wird wie so oft über Width und Height definiert.

Es gibt zwei unterschiedliche Darstellung für einen ProgressBar:

  • man kann den ProgressBar dazu nutzen, einen fortlaufenden oder anhaltenden Zustand anzuzeigen, der nicht terminiert, und ein Ende nicht abzulesen ist, der ProgressBar zeigt, deshalb nur einen Musterverlauf an. Dieses Verhalten kann mit dem Parameter IsIndeterminate=”True” herbei geführt werden.
  • Wenn ein Fortschritt sichtbar sein kann bzw. es zu einem Ende kommt, wie zB beim Laden eines Bildes, braucht man keinen Parameter dafür extra angeben, weil IsIndeterminate defaultmäßig auf false gesetzt ist.

Über den Parameter Value erhält man den aktuellen Fortschritt bzw. könnte auch einen Wert setzen, der Wertebereich reicht von 0 bis 100. Ein Vorgang muss aber nicht immer bei 0 Anfangen bzw. bei 100 aufhören, man kann den Start und Endwert auch über Minimum bzw. Maximum ändern. Eine Möglichkeit ist es, die Anzeige für Zeitmäßiges laden zu verwenden, dafür müsste man den Bereich nur auf 60 Einheiten beschränken.

Der Event-Handler für den ProgressBar ist das ValueChanged-Event, das immer dann Eintritt wenn sich der Value-Wert ändert. Man könnte meinen, dass dies nicht besonders sinnvoll ist, da die Werte ja händisch geändert werden. Aber man kann eine Klasse vom ProgressBar ableiten, über das sich das ValueChange-Ereignis selbst abprüft. Beim erstmaligen Auftreten wird der Balken sichtbar gemacht und wenn man 100 erreicht wird, dann wird die Sichtbarkeit deaktiviert.

Alternativ könnte man den Download-Fortschritt auch als Zahl anzeigen.

Daily Hour 34: Steuerelement Teil 9: Mediaelement

24. Februar 2010 juergen79 Keine Kommentare

Um multimediale Inhalte online zu stellen gibt es in Silverlight das MediaElement-Control. Audio- und Videoformate unterliegen häufigen Formatänderungen und -verbesserungen. Welche Formate werden von Silverlight unterstützt?

  • Video:
    • RAW-Video
    • YV12 – YCrCb(4:2:0)
    • RGBA – 32-Bit-Alpha Rot, Grün, Blau
    • WMV1: Windows Media Video 7
    • WMV2: Windows Media Video 8
    • WMV3: Windows Media Video 9
    • WMVA: Windows Media Video Advanced Profile, non-VC-1
    • WVC1: Windows Media Video Advanced Profile, VC-1
    • H264 (ITU-T H.264/ISO MPEG-4 AVC)
  • Audio
    • WAV: lineare 8- und 16-Bit Pulscodemodulation
    • WMA Standard: Windows Media Audio v7, v8, v9.x Standard
    • WMA Professional: Windows Media Audio v9.x – v10 Professional
    • AAC: ISO Advanced Audio Coding

Weiters werden folgende Webprotokolle/-shemas unterstützt:

  • http
  • https
  • ms-wmsp (es können auch die Moniker mms und rtsp verwenden, werden aber in http-streaming geändert)
  • UNC (\\computername\freigabeverzeichnis) – zu beachten gilt, das dies als Stream abgerufen werden muss.

So jetzt sind die wichtigsten Formate und Protokolle besprochen, wird es Zeit ein MediaElement zu definieren:

<MediaElement source=”video.wmv” x:Name=”Vid”/>

Wie beim Image sind auch beim MediaElement die meisten Eigenschaften verwendbar, wie

  • Stretch
  • Width/Height
  • Brushes

Wie bei Image können die Mediendatein innerhalb der XAP-Datei gespeichert werden oder auf einer externen Quelle befinden.

Im allgemeinen gibt es 3 Arten wie eine Mediendatei abgespielt werden kann:

  • Download: die Datei wird erst auf die lokale Festplatte geladen und sobald diese komplett ist, wird diese abgespielt.
  • Progressiver Download: hierbei wird nicht gewartet bis das File vollständig heruntergeladen ist, sondern immer teile (gepuffert) und dann mit dem Abspielen begonnen. Die Datei wird im normalfall ohne Verzögerung abgespielt, aber ist von der Bandbreite der Internetverbindung abhängig
  • Streaming: hier wird die Datei nie komplett heruntergeladen, sondern immer nur häppchenweise. Im Unterschied zum progressiven Download, der Puffer überschreibt sich ständig selbst und die Datei wird niemals komplett heruntergeladen.

Defaultmäßig ist AutoPlay auf true gesetzt, d. h. die Datei wird gleich abgespielt. Sollte jedoch mit dem abspielen der Datei gewartet werden, so ist der Wert auf false zu setzen. Eine weitere Erweiterung gegenüber ist Volume, der als Double-Wert definiert ist, hier kann die Lautstärke von 1 (volle Lautstärke) bis 0 (Mute), abhängig von der Systemlautstärke eingestellt werden. Um den Ton stumm zu schalten gibt es mit IsMute eine weitere Möglichkeit dies zu tun, der Vorteil, soll der Ton wieder aktiviert werden, so wird bei der letzten eingestellten Lautstärke der Ton wieder ausgegeben. Eine weitere Audio-Eigenschaft ist Balance (ebenfalls ein Double) mit dem die Balance zwischen rechten und linken Lautsprecher eingestellt werden kann, der Wertebereich liegt von -1 bis 1. -1 ist der linke Lautsprecher, 0 ausgeglichen und 1 der rechte.

Das MediaElement kann sich abhängig von der aktuellen Aktion verschiedene Zustände annehmen. Zustandsänderung des MediaElements führ zu einem CurrentStateChanged. Hierbei sind folgende States möglich:

  • Opening: Media-Datei wird validiert und für den Empfang vorbereitet, anschließend wir das Opened-Ereignis ausgelöst
  • Buffering: die ersten Sequenzen der Media-Datei werden heruntergeladen und in den Puffer geschrieben.
  • Playing: die Datei wird abgespielt
  • Paused
  • Stopped
  • Closed: zeigt keinen Inhalt an und es ist keine Mediadatei mehr vorhanden/geöffnet

Wichtige Ereignise im Zusammenhang mit MediaElementen sind:

  • BufferingProgressChanged
  • DownloadProgressChanged
  • MediaOpened
  • MediaFailed
  • MediaEnded
  • MarkerReached

Wie man diese Elemente einsetzen kann, wird in einem der folgenden Einträge zum Thema “Mediaplayer” behandelt.

Daily Hour 33: Steuerelement Teil 8: HyperlinkButton & Image

23. Februar 2010 juergen79 Keine Kommentare

HyperlinkButton

Mit dem HyperlinkButton kann man Hyperlinks im Silverlight-PlugIn verwenden und ist ein Content-Control, d.h. er kann Text, Bilder Figuren oder Bereichselemente enthalten. Die am meisten verwendete Variante ist der Content-Parameter und stellt einen Text als Hyperlink dar. Der Vorteil ist, das der Link schon standardmäßig vordefiniert ist.

In XAML ist der Standard-HyperlinkButton einfach zu definieren:

<HyperlinkButton Content=”Microsoft Silverlight Website”  NavigateUri=”http://www.silverlight.net” TargetName=”_blank” Margin=”5″/>

Mit dem Content-Parameter definiert man den Text mittels der Eigenschaft Underline könnte man den Link wie aus HTML-Dokumenten gewohnt aussehen lassen. NavigateUrl weißt man die URL, die aufgerufen werden soll, zu. Dann wäre noch TargetName zu erwähnen, diese Eigenschaft dient um fest zu legen, wie die URL aufgerufen werden soll. Wie aus HTML-Dokumenten gewohnt:

  • _blank: Die URL wird in einem neuen Fenster/Tab geöffnet.
  • _self: Die URL wird im gleichen Frame oder Browserfenster geöffnet. Dies ist auch die Standardmäßige Definition, falls nichts anderes angeführt wird.

Wie bei Content-Elementen bekannt, verfügt auch der HyperlinkButton über die Eigenschaften: Background, Border, BorderThickness, ClickMode und Font um den Button auch anpassen zu können. Mittels den Eventen MouseEnter und MouseLeave können zusätzliche Effekte umgesetzt werden, wie z das Färben des Links, wenn der Mauszeiger in den Bereich eindringt.

Image

Wann man sich das nächste Steuerelement Image anschaut, ist das Einbinden eines Bilds in eine Silverlight-Applikation relativ einfach und mit wenig XAML bereits erledigt:

<Image Source=”Penguins.jpg” />

Dabei kann man das anzuzeigende Bild über eine URI angegeben werden oder es ist Inhalt der XAP-Datei bzw. wird als Ressource in die DLL kompliert. Die häufigste Form ist das es Teil der XAP Datei ist oder liegt am selben Server, der auch die XAP-Datei bereitstellt.

Mit Source wird der Pfad und Dateiname des Bildes angegeben.

In Silverlight werden Bildformat JPEG und PNG untersützt, aber es werden nicht alle PNG-Spezifikationen enthalten. Silverlight unterstützt folgende Farbtiefen:

  • indizierte Farbe (1-Bit, 4-Bit oder 8-Bit-Farbtiefe pro Kanal).

  • Truecolor (24-Bit-Farbtiefe oder 32-Bit-Farbtiefe (pro Kanal) für Truecolor.
    Alpha wird in 32-Bit-, aber nicht in 24-Bit-PNG-Dateiformaten unterstützt.

Graustufen-PNGs werden noch nicht unterstützt.

Es kann auch vorkommen, das ein Bild nicht aufgefunden werden kann oder es sich um ein nicht unterstütztes Format handelt bzw. könnte auch die Datei defekt sein, deshalb gibt es das ImageFailed-Event, das ausgelöst wird, wenn es zu Problemen mit dem Aufruf der Datei kommt.

Es kann zwischen der Anfrage und Emfang zu Verzögerungen kommen, die normalerweise kaum bemerkbar sind, aber bei größeren Bildern sichtbar wir und zu mehrsekündigen Verzögerungen kommen könnte. Man spricht hier vom asynchronen Prozess. Silverlight kümmert sich zwar darum, das auf dem Empfang gewartet ist, dekodiert anschließend auch das Bild und zeigt es danach an. In XAML hat man keine Möglichkeit auf den Fortschritt des Downloads zu reagieren. Eine erfolgreiche Darstellung kann man nur feststellen, da kein ImageFailed-Event ausgelöst wird.
 
Aber durch den Code könnte man sich abhilfe schaffen. Man kann einerseits wie erwähnt mittels dem ImageFailed Parameter einen Event-Handler implementieren, der Alternativen zu Darstellung eines Bildes bietet oder auch einen Progressbar, damit der Anwender die Fortschritte beim laden des Bildes ersichtlich
        private void pic_Loaded(object sender, RoutedEventArgs e)
        {
            BitmapImage img = new BitmapImage(new Uri(“Pinguins.jpg”));
            img.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(img_DownloadProgress);
            pic.Source = img;
        }

Zuerst erzeugt man ein Bitmap-Objekt, der Bitmap-Instanz wird schließlich ein Event-Handler zugewiesen, der den Fortschritt des Downloads anzeigt. Abschließend wird dem Image Bild dieses BitmapImage direkt zugewiesen

        private void img_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            progress.Value = e.Progress;
            if (e.Progress == 100) progress.Visibility = Visibility.Collapsed;

        }

Der ProgressBar progress wird hier noch ein Wert zugewiesen, der den Fortschritt des Downloads anzeigt. Sollte das Bild schließlich vollständig geladen sein, wird der ProgressBar ausgeblendet.

Am Ende sollte noch kurz die Darstellungsmöglichkeiten des Bildes besprochen werden. Sollten zur Höhe und Breite des Bildes keine Angaben gemacht, wird das Bild in der Originalgröße dargestellt. Oft weiß man nicht, wie Groß der Ausgabebildschirm sein wird und da sind fixe Größenbeschränkungen sind da nicht optimal, besser ist es dafür Width und Height des Image-Controls festzulegen und dafür zu sorgen, das eine Darstellung des Bildes schön angezeigt wird, dafür gibt es den Parameter Stretch.

  • Non: es findet keine Anpassung des Bildes statt es wird so dargestellt, das die Originalgröße des Bildes erhalten bleiben. Dabei kann das Bild größer oder kleiner sein, als der definierte “Rahmen”.
  • Fill: Das Bild wird exakt an die Größe der BoundingBox angepasst. Die BoundingBox entspricht in dem Fall der definierten Höhe und Breite. Beim Bild kann es dadurch zu Verzerrungen kommen kann.
  • Uniform: Das Bild wird bestmöglich an die BoundingBox angepasst (entweder Breite oder Höhe des Bildes). Hierbei wird auf einer der es zu “Rändern” kommen, da nur eine Seite des angepasst wird und die andere Verhältnismäßig angepasst.
  • UniformToFill: Hier wird das Bild so angepasst, dass die BoundingBox komplett ausgefüllt werden kann, ohne das die Seitenverhältniss des Bildes zu zerstören. Die kleinere Seite wird angepasst, die größere wird beschnitten.

  • Uniform