Archiv

Archiv für März, 2010

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.