Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Über den Autor
Vorwort zur 4. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign und Vererbung
4 Weitere .NET-Datentypen
5 Weitere Möglichkeiten von C#
6 Projektmanagement und Visual Studio 2008
7 Fehlerbehandlung und Debugging
8 LINQ
9 Multithreading und asynchrone Methodenaufrufe
10 Arbeiten mit Dateien und Streams
11 Serialisierung
12 Einige wichtige .NET-Klassen
13 Grundlagen zum Erstellen einer Windows-Anwendung
14 Die wichtigsten Steuerelemente
15 Tastatur- und Mausereignisse
16 MDI-Anwendungen
17 Grafische Programmierung mit GDI+
18 Das Drucken (Printing)
19 Steuerelemente entwickeln
20 Programmiertechniken
21 WPF – die Grundlagen
22 Die Layoutcontainer
23 Die WPF-Controls
24 Konzepte von WPF
25 ADO.NET – die Verbindung zu einer Datenbank herstellen
26 Die Datenbankabfrage
27 Der SqlDataAdapter
28 Daten im lokalen Speicher – das DataSet
29 Eine Datenbank aktualisieren
30 Stark typisierte DataSets
31 Weitergabe von Anwendungen
Stichwort

Download:
- ZIP, ca. 13,6 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2008 von Andreas Kuehnel
Das umfassende Handbuch
Buch: Visual C# 2008

Visual C# 2008
geb., mit DVD
1.366 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1172-7
Pfeil 24 Konzepte von WPF
Pfeil 24.1 Ressourcen
Pfeil 24.1.1 Eine Ressource definieren
Pfeil 24.1.2 Statische und dynamische Ressourcen
Pfeil 24.1.3 Abrufen von Systemressourcen
Pfeil 24.2 Stile
Pfeil 24.2.1 Eine einfache Style-Definition
Pfeil 24.2.2 Typisierte Stile
Pfeil 24.3 Trigger
Pfeil 24.3.1 Eigenschaftstrigger
Pfeil 24.3.2 Ereignistrigger
Pfeil 24.3.3 Datentrigger
Pfeil 24.4 Commands
Pfeil 24.4.1 Vordefinierte Commands
Pfeil 24.4.2 Beispielanwendung
Pfeil 24.4.3 Das Commando-Ziel festlegen
Pfeil 24.4.4 Commands an Ereignisse binden
Pfeil 24.4.5 Commands programmieren
Pfeil 24.5 Datenbindung
Pfeil 24.5.1 Eine einfache Datenbindung
Pfeil 24.6 Bindungsmodi
Pfeil 24.6.1 Aktualisierung der Quelle
Pfeil 24.6.2 Verschiedene Datenbindungsquellen
Pfeil 24.6.3 Collections anbinden

24 Konzepte von WPF

WPF erweitert die Eigenschaften der Common Language Runtime (CLR) um zwei besondere Gruppen:

  • Abhängige Eigenschaften (Dependency Properties)
  • Angehängte Eigenschaften (Attached Properties)

Beide werden ähnlich wie »normale« Eigenschaften verwendet, werden aber anders deklariert.

Abhängige Eigenschaften

Stellen Sie sich vor, im Auslieferungslager eines Unternehmens befindet sich der Artikel A. Mit dem Artikel ist ein bestimmter Verkaufspreis verknüpft. Wird der Artikel ins Ausland verkauft, in dem eine andere Währung Zahlungsmittel ist, muss der Verkaufspreis eventuell an den aktuellen Wechselkurs dynamisch angepasst werden. Damit wäre der Verkaufspreis eine abhängige Eigenschaft.

Abhängige Eigenschaften bieten im Vergleich mit den herkömmlichen Eigenschaften Vorteile:

  • Die Werte werden automatisch aktualisiert.
  • Zur Signalisierung von Wertänderungen werden Callback-Methoden verwendet.
  • Es kann eine interne Validierung erfolgen.
  • Es können Standardwerte definiert werden.

Die Einführung von abhängigen Eigenschaften war notwendig, um die vielen WPF-Features realisieren zu können, da einige davon abhängen, ob sich im System oder in der Anwendung Eigenschaftswerte verändert haben. Zu den Features, die grundlegend auf abhängige Eigenschaften angewiesen sind, gehören beispielsweise die Datenbindung und Animationen.

An einem Beispiel wollen wir uns nun ansehen, wie eine abhängige Eigenschaft in einer Klasse definiert wird. Dazu definieren wir eine Klasse Line, die von DependencyObject abgeleitet wird.

class Line : DependencyObject { 
  // die abhängige Eigenschaft 
  public static readonly DependencyProperty LengthProperty;

  // Registrieren der abhängigen Eigenschaft 
  static Line() { 
    Line.LengthProperty = DependencyProperty.Register( 
          "Length", typeof(int), typeof(Line), 
          new FrameworkPropertyMetadata(10, 
          new PropertyChangedCallback(OnLengthChanged))); 
  }

  // Schnittstelle der Eigenschaft nach draußen 
  public int Length { 
    get { 
      return (int)GetValue(Line.LengthProperty); 
    } 
    set { 
      SetValue(Line.LengthProperty, value); 
    } 
  }

  // Callback-Methode 
  private static void OnLengthChanged(DependencyObject dpObj, 
              DependencyPropertyChangedEventArgs e) { 
    // ... 
  } 
}

Abhängige Eigenschaften sind vom Typ DependencyProperty. Sie müssen als öffentliche statische Felder definiert werden. Die Verwaltung abhängiger Eigenschaften wird vom WPF-Subsystem übernommen. Aus diesem Grund müssen abhängige Eigenschaften mit der Methode Register registriert werden. Dem Aufruf werden der Name der Eigenschaft (hier: Length), der Typ der Eigenschaft und die Klasse übergeben, die die abhängige Eigenschaft hostet. Zudem werden bei der Registrierung ein Standardwert und eine Rückrufmethode festgelegt.

In der Eigenschaftsmethode werden GetValue und SetValue aufgerufen. Beide sind Eigenschaften der Klasse DependencyObject. GetValue liefert den letzten an SetValue gelieferten Wert. Solange SetValue nicht aufgerufen worden ist, wird der Standardwert zurückgeliefert. Genau genommen muss keine Eigenschaftsmethode implementiert werden, da GetValue und SetValue öffentlich in DependencyObject definiert sind.

Von der Callback-Methode werden schließlich alle Wertänderungen überwacht.

Angehängte Eigenschaften

Eine besondere Variante der abhängigen Eigenschaften sind die angehängten Eigenschaften (Attached Properties). Abhängige Eigenschaften sind in einem übergeordneten Element definiert. Üblicherweise handelt es sich dabei um einen Container wie beispielsweise um Grid oder StackPanel. Angehängte Eigenschaften stehen in einem untergeordneten Element zur Verfügung, ohne dass die Eigenschaft in diesem definiert ist. Der Vorteil bei diesem Verfahren ist, dass sich die Anzahl der eigentlichen Eigenschaften für die Komponente verringert.

Betrachten wir dazu ein Beispiel. In einem Grid soll eine TextBox positioniert werden. Die Eigenschaften Grid.Column und Grid.Row sind Eigenschaften, die vom Grid der TextBox zur Verfügung gestellt werden.

<Grid> 
  <TextBox Grid.Column="0" Grid.Row="0" Name="txtText" >Hallo</TextBox> 
</Grid>

Sie können die Position der TextBox auch mittels Code ändern, müssen dann aber die Eigenschaften SetColumn und SetRow des Grid-Controls aufrufen.

Grid.SetColumn(txtText, 1); 
Grid.SetRow(txtText, 2);

Galileo Computing - Zum Seitenanfang

24.1 Ressourcen Zur nächsten ÜberschriftZur vorigen Überschrift

In WPF-Anwendungen werden häufig Bilder, Grafiken und ähnliche Dateien benötigt. Diese werden als Ressourcen bereitgestellt. Eine Ressource muss über einen Schlüssel (Key) eindeutig identifizierbar sein und kann auch später durch eine andere Ressource ersetzt werden. Typische Ressourcen sind Füllmuster, geometrische Objekte oder Stile.

Ressourcen lassen sich nahezu jedem Objekt hinzufügen und müssen nicht an einer zentralen Stelle verwaltet werden. Um eine Ressource anwendungsweit bereitzustellen, definieren Sie die Ressource in der Datei App.xaml, in der ein Abschnitt für die Ressourcen bereits vordefiniert ist.

<Application x:Class="WpfApplication4.App" 
             xmlns=http://... 
             xmlns:x=http://... 
             StartupUri="Window1.xaml"> 
  <Application.Resources>

  </Application.Resources> 
</Application>

Auf die Ressourcen, die hier definiert sind, haben alle Elemente gleichermaßen Zugriff, sowohl alle Window- als auch alle Steuerelemente.

Sie können auch einen Ressourcenbereich im Window festlegen. Allerdings müssen Sie diesen Bereich manuell angeben:

<Window x:Class="WpfApplication4.Window1" 
  xmlns="http://..." 
  xmlns:x="http://..." 
  Title="Window1" Height="259" Width="516" 
  <Window.Resources> 
    <!-- windowseigene Ressourcen --> 
  </Window.Resources> 
</Window>

In gleicher Weise lässt sich auch ein Abschnitt für Ressourcen beispielsweise in einem Button oder für Ressourcen eines Grid definieren:

<Grid> 
  <Grid.Resources> 
    <!-- Ressourcen des Grid --> 
  </Grid.Resources> 
  <Button> 
    <Button.Resources> 
      <!-- Ressourcen des Button --> 
    </Button.Resources> 
  </Button> 
</Grid>

Zusätzlich zu den genannten Ressourcen sind auch noch Systemressourcen verfügbar.

Bei so vielen unterschiedlichen Ebenen, in denen Ressourcen bereitgestellt werden können, stellt sich unweigerlich die Frage, nach welchem Muster die Suche nach einer Ressource abläuft. Der Ablauf der Suche ist sehr einfach: Sie beginnt immer beim aktuellen Element, beispielsweise dem Button. Wird die Ressource hier nicht gefunden, setzt sich die Suche im nächsten übergeordneten Element fort. Hier könnte es sich beispielsweise um einen Grid-Container handeln. Wenn die Suche auch hier nicht zum Erfolg führt, wird unter den Window-Ressourcen gesucht, danach gegebenenfalls noch in den Application-Ressourcen. Das Ende der Kette wird durch die Systemressourcen beschrieben.


Galileo Computing - Zum Seitenanfang

24.1.1 Eine Ressource definieren Zur nächsten ÜberschriftZur vorigen Überschrift

Jetzt wissen Sie, wo Ressourcen definiert werden können und in welcher Reihenfolge sie ausgewertet werden. Nun ist es an der Zeit, sich das an einem Beispiel anzusehen.

Im folgenden Beispiel sind zwei Ressourcen im Ressourcenbereich des Window definiert. Eine Ressource beschreibt einen blauen Farbton, die zweite einen gelben. Vier Schaltflächen sind dem Fenster zugeordnet. Zwei greifen auf beide Ressourcen zu, ein Button nutzt nur eine und der letzte überhaupt keine.

// ---------------------------------------------------------
// Beispiel: ...\Kapitel 24\Ressourcen
// -------------------------------------------------------------
<Window x:Class="Ressourcen.Window1" ...> 
  <Window.Resources> 
    <SolidColorBrush x:Key="backgroundBlue"> 
                     CornflowerBlue</SolidColorBrush> 
    <SolidColorBrush x:Key="borderYellow" Color="Yellow" /> 
  </Window.Resources>

  <StackPanel> 
    <Button BorderBrush="{StaticResource borderYellow}" 
            Background="{StaticResource backgroundBlue}" 
            Height="40">Button1</Button> 
    <Button BorderBrush="{StaticResource borderYellow}" 
            Background="{StaticResource backgroundBlue}" 
            Height="40">Button2</Button> 
    <Button Background="{StaticResource backgroundBlue}" 
            Height="40">Button3</Button> 
    <Button Height="40">Button3</Button> 
  </StackPanel> 
</Window>

Abbildung 24.1 Vier Schaltflächen, die eine Ressource nutzen

Wichtig ist, der Ressource einen eindeutigen Schlüssel zu geben, unter der sie aufrufbar ist. In unserem Beispiel lauten die beiden Schlüssel wie folgt:

x:Key="backgroundBlue 
x:Key="borderYellow

Beim Zugriff auf eine Ressource müssen Sie beachten, die Groß-/Kleinschreibung zu berücksichtigen. Die gewünschte Ressource wird in geschweiften Klammern angegeben:

Background="{StaticResource backgroundBlue}

Es gibt darüber hinaus auch noch eine zweite Schreibweise, um auf eine Ressource zuzugreifen:

<Button Height="40"> 
  <Button.Background> 
    <StaticResource ResourceKey="backgroundBlue" /> 
  </Button.Background>Button3 
</Button>

Galileo Computing - Zum Seitenanfang

24.1.2 Statische und dynamische Ressourcen Zur nächsten ÜberschriftZur vorigen Überschrift

Statische Ressourcen

Im vorigen Beispiel wurden statische Ressourcen verwendet. Wird eine Ressource statisch an eine Eigenschaft gebunden, wird der Wert der Ressource nur ein einziges Mal ausgewertet und der Eigenschaft zugewiesen. Ändert sich danach eine Ressource, wird der neue Wert nicht mehr berücksichtigt.

Die Anbindung an eine Ressource erfolgt mit StaticResource. Diese Markup-Erweiterung wird zusammen mit dem eindeutigen Bezeichner der Ressource in geschweiften Klammern der Eigenschaft übergeben. Die angegebene Ressource muss natürlich existieren, da ansonsten eine Exception ausgelöst wird.

Dynamische Ressourcen

Soll sich eine Ressource zur Laufzeit ändern, müssen Sie eine dynamische Ressource definieren, denn statische Ressourcen bemerken Änderungen nicht. Dynamische Ressourcen werden von WPF automatisch auf Änderungen hin geprüft. Das kostet Rechenzeit, worunter die Performance der Anwendung ein wenig leidet.

Dynamische Ressourcen haben gegenüber den statischen nicht nur in der Aktualisierbarkeit einen Vorteil. Darüber hinaus muss eine dynamische Ressource nicht sofort verfügbar sein. Sie kann später bereitgestellt werden. WPF bemerkt die Bereitstellung und stellt sofort eine Verbindung her.

Die Festlegung dynamischer Ressourcen kann im Programmcode erfolgen. Im folgenden Beispiel wird der Hintergrund einer Schaltfläche beim Klicken auf dieselbe durch eine dynamische Ressource aus dem Code heraus geändert. Die Ressource wird im Code des Ereignishandlers dem Window-Objekt zugeteilt.

// ---------------------------------------------------------
// Beispiel: ...\Kapitel 24\DynamischeRessourcen
// -------------------------------------------------------------
<Window x:Class="DynamischeRessourcen.Window1" 
                 xmlns="http://..." 
                 xmlns:x="http://..." 
                Title="Window1" Height="100" Width="300"> 
  <StackPanel> 
    <Button Background="{DynamicResource hintergrund}" 
            Name="button1" Height="40" 
            Click="button1_Click"> 
      Button1 
    </Button> 
  </StackPanel> 
</Window>

Der Code in der Code-Behind-Datei sieht so aus:

private void button1_Click(object sender, RoutedEventArgs e) { 
  LinearGradientBrush color = 
     new LinearGradientBrush(Colors.Yellow, Colors.Blue, 0); 
  this.Resources.Add("hintergrund", color); 
}

Abbildung 24.2 Schaltfläche, die eine dynamische Ressource nutzt


Galileo Computing - Zum Seitenanfang

24.1.3 Abrufen von Systemressourcen topZur vorigen Überschrift

Bisher haben wir nur definierte Ressourcen verwendet. Sie können aber auch auf Ressourcen zugreifen, die vom System bereitgestellt werden. WPF enthält drei Klassen, mit denen sich bestimmte Eigenschaften des Systems auswerten lassen:

  • SystemParameters
  • SystemColors
  • SystemFonts

SystemFonts beschreibt Eigenschaften, die die Systemressourcen für Schriftarten verfügbar machen, SystemColors beschreibt die vom System verwendeten Farben, und SystemParameters enthält Eigenschaften, die Sie zum Abfragen von Systemeinstellungen verwenden können.

Wenn Sie sich die Dokumentation dieser Klassen ansehen, werden Sie feststellen, dass für jede Systemeigenschaft zwei Eigenschaften definiert sind, beispielsweise CaptionWidth und CaptionWidthKey in der Klasse SystemParameters. Doch wozu braucht man zwei ähnliche Eigenschaften?

CaptionWidth liefert einen double-Wert als Ergebnis, der die Breite der Titelleiste beschreibt. Der Rückgabetyp von CaptionWidthKey ist jedoch vom Typ ResourceKey. Wenn Sie auf eine Ressource statisch zugreifen möchten, reicht die Angabe der Eigenschaft ohne das Suffix Key vollkommen aus. In diesem Fall reagiert die Anwendung nicht auf Änderungen an den Systemeinstellungen.

Sehen wir uns zuerst eine statische Ressourcenabfrage an. Beachten Sie, dass für den Zugriff auf die Systemressourcen die Markup-Erweiterung x:Static vorgeschrieben ist.

<Label Content="{x:Static SystemParameters.CaptionWidthKey}" />

Denselben Zugriff, nun allerdings dynamisch, zeigt die folgende Anweisung:

<Label Content="{StaticResource {x:Static SystemParameters.CaptionWidthKey}}" />


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2008






Visual C# 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Coding for Fun






 Coding for Fun


Zum Katalog: Einstieg in Visual C# 2008






 Einstieg in
 Visual C# 2008


Zum Katalog: Videotraining - Visual C# 2008






 Videotraining -
 Visual C# 2008


Zum Katalog: Fortgeschrittene Programmierung mit Visual C# 2008






 Fortgeschrittene
 Programmierung mit
 Visual C# 2008


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Visual Basic 2008






 Visual Basic 2008


Zum Katalog: Einstieg in XML






 Einstieg in XML


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de