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

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 23 Konzepte von WPF
Pfeil 23.1 Anwendungsspezifische Ressourcen
Pfeil 23.2 Anwendungsübergreifende Ressourcen
Pfeil 23.2.1 Mehrere Ressourcenwörterbücher
Pfeil 23.2.2 Die Suche nach einer Ressource
Pfeil 23.3 Logische Ressourcen
Pfeil 23.3.1 Statische Ressourcen
Pfeil 23.3.2 Dynamische Ressourcen
Pfeil 23.3.3 Ressourcen mit C#-Code bearbeiten
Pfeil 23.3.4 Abrufen von Systemressourcen
Pfeil 23.4 Styles
Pfeil 23.4.1 Einfache Styles
Pfeil 23.4.2 Typisierte Styles
Pfeil 23.4.3 Erweitern von Styles
Pfeil 23.4.4 EventSetter
Pfeil 23.5 Trigger
Pfeil 23.5.1 Eigenschaftstrigger
Pfeil 23.5.2 Datentrigger
Pfeil 23.5.3 Ereignistrigger
Pfeil 23.6 Templates
Pfeil 23.6.1 Allgemeines zu »ControlTemplates«
Pfeil 23.6.2 Definition innerhalb eines Styles
Pfeil 23.7 Ermitteln des visuellen Elementbaums
Pfeil 23.7.1 Das Tool »Expression Blend«
Pfeil 23.7.2 Standard-Template mit Code abfragen

Rheinwerk Computing - Zum Seitenanfang

23.4 StylesZur nächsten Überschrift

Das Layout grafischer Komponenten können Sie im XAML-Code nahezu beliebig konfigurieren. Das Einstellen der individuellen Eigenschaften für Font, Farbe, Größe usw. ist aber mit einem nicht unbeträchtlichen Aufwand verbunden. Insbesondere wenn mehrere Steuerelemente einheitlich gestaltet werden sollen, ist das Endergebnis eine riesige XAML-Datei, in der die Einstellungen der Controls redundant auftreten.

An dieser Stelle betreten die Styles die Bühne der WPF. Styles gestatten das Zusammenfassen mehrerer Einstellungen, die zentral zur Verfügung gestellt werden. Das Prinzip erinnert an das von CSS (Cascading Style Sheets) in HTML. Allerdings werden Styles nicht in separate Dateien verpackt, sondern als logische Ressourcen angeboten. Daraus folgt, dass Styles lokal im Fenster, in der App.xaml-Datei oder in einem externen Ressourcenwörterbuch bereitgestellt werden können. Weil Styles in der Regel dazu benutzt werden, der Anwendung ein einheitliches, leicht und zentral änderbares Layout zu geben, scheidet in vielen Fällen die lokale Definition in einem Fenster aus.


Rheinwerk Computing - Zum Seitenanfang

23.4.1 Einfache StylesZur nächsten ÜberschriftZur vorigen Überschrift

Das Prinzip einer Style-Definition soll sofort an einem Beispiel gezeigt werden. Nehmen wir dazu zunächst an, Sie möchten ein Window bereitstellen, in dem sich drei Schaltflächen befinden. Alle Schaltflächen sollen als besonderes Design einen Farbverlauf haben, der mittels XAML-Code in jeder der drei Schaltflächen angegeben wird.

[...]
<Button Height="35" Margin="10">
<Button.Background>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Button.Background>
<Button.FontSize>18</Button.FontSize>
Button1
</Button>
<Button Height="35" Margin="10">
<Button.Background>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Button.Background>
<Button.FontSize>18</Button.FontSize>
Button2
</Button>
<Button Height="35" Margin="10">
<Button.Background>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Button.Background>
<Button.FontSize>18</Button.FontSize>
Button3
</Button>

Listing 23.14 Drei Schaltflächen mit gleichem Design

Das Problem des redundanten Codes wird in diesem kleinen Beispiel bereits deutlich, denn bis auf die Beschriftung ist der Code für alle drei Schaltflächen identisch. Zudem wirkt der XAML-Code unübersichtlich.

Die Gemeinsamkeiten der drei Schaltflächen sollen nun von einem Style beschrieben werden, der von den Schaltflächen gemeinsam genutzt wird. Styles werden in einem Resources-Abschnitt definiert. Daher bieten sich insgesamt vier Bereitstellungsorte an:

  • Styles können direkt im Element angegeben werden. Allerdings ist das eher eine theoretische Option, die ausscheidet, da der Style nur von der betreffenden Komponente genutzt werden könnte.
  • Etwas besser ist es, Styles im Resources-Abschnitt des Window-Objekts anzugeben. Die Nutzbarkeit ist so auf das aktuelle Fenster beschränkt, andere Fenster können von dem Style nicht profitieren. Eine Ausnahme wäre beispielsweise, wenn es sich bei dem Fenster um das Hauptfenster der Anwendung handeln würde, dem alle anderen Fenster untergeordnet sind.
  • Damit alle Komponenten eines Programms von einer Style-Definition gleichermaßen profitieren können, sollten Sie den Style global beschreiben. Dafür eignet sich die Datei App.xaml oder – anwendungsübergreifend – ein externes Ressourcenwörterbuch.

Nun sollten wir uns zuerst die Lösung mit einer Style-Definition ansehen.

// Beispiel: ..\Kapitel 23\SimpleStyle
<Window x:Class="SimpleStyle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SimpleStyle" Height="180" Width="300">
<StackPanel>
<Button Style="{StaticResource btnStyle}">
Button1
</Button>
<Button Style="{StaticResource btnStyle}">
Button2
</Button>
<Button Style="{StaticResource btnStyle}">
Button3
</Button>
</StackPanel>
</Window>

Listing 23.15 XAML-Code des Beispielprogramms »SimpleStyle«

In der App.xaml-Datei ist der Style als Ressource definiert:

<Application x:Class="SimpleStyle.App" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="btnStyle">
<Setter Property="Button.Height" Value="35" />
<Setter Property="Button.FontSize" Value="18" />

<Setter Property="Button.Margin" Value="10" />
<Setter Property="Button.Background">
<Setter.Value>

<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>

</Application.Resources>
</Application>

Listing 23.16 Style-Definition in der Datei »App.xaml«

Abbildung

Abbildung 23.4 Die Ausgabe des Beispielprogramms »SimpleStyle«

Styles sind logische Ressourcen und werden durch das Element Style beschrieben. Mit x:Key erhält jeder Style einen Schlüssel, unter dem er aufrufbar ist:

<Style x:Key="btnStyle">

Die Eigenschaften, die ein Style vordefinieren soll, werden durch Setter-Elemente beschrieben. Dessen Attribut Property gibt die Eigenschaft an. Die Bezeichnung setzt sich aus dem Typ der Zielkomponente und dem Namen der Eigenschaft zusammen. Die Angabe ist notwendig, damit WPF die Abhängigkeitseigenschaft korrekt auflösen kann.

Es gibt eine Bedingung hinsichtlich der Eigenschaften, die in Setter Property genannt werden können: Es muss sich um eine Abhängigkeitseigenschaft (Dependency Property) handeln.

Über das Attribut Value teilen Sie den Wert mit, z. B.:

<Setter Property="Button.Height" Value="35" />

Um komplexere Eigenschaftswerte zu definieren, können Sie beim Attribut Value auch auf die Eigenschaft-Element-Schreibweise zurückgreifen. In unserem Beispiel oben wird das anhand der Eigenschaft Background gezeigt.

Da es sich bei einer Style-Definition um eine Ressource handelt, kann eine Komponente den Stil mit der Markup-Erweiterung StaticResource oder DynamicResource nutzen.

<Button Style="{StaticResource btnStyle}">

Den Elementen, die einen vordefinierten Style nutzen sollen, muss das ausdrücklich mitgeteilt werden. Dafür weisen alle Typen, die von FrameworkElement abgeleitet sind, die in dieser Klasse definierte Eigenschaft Style auf. Dazu wird der Style über die Markup-Extension StaticResource oder DynamicResource referenziert.

<Button Style="{StaticResource btnStyle}">

Rheinwerk Computing - Zum Seitenanfang

23.4.2 Typisierte StylesZur nächsten ÜberschriftZur vorigen Überschrift

Es ist möglich, bereits dem Element Style den Zieldatentyp bekannt zu geben, an den sich die Eigenschaftseinstellungen richten. Der Zieldatentyp wird mit dem Attribut TargetType angegeben, z. B.:

<Style TargetType="{x:Type Button}">

Im Gegensatz zu den Aussagen im letzten Abschnitt fehlt hier nur die Angabe von x:Key. Das Zielelement bereits in der Style-Definition zu nennen hat den Vorteil, dass die Steuerelemente dieses Typs den Style nicht mehr referenzieren müssen, denn er wird automatisch auf alle Steuerelemente des angegebenen Typs angewendet. Allerdings können Sie die damit frei gewordene Style-Eigenschaft eines Steuerelements nicht dazu benutzen, um einen weiteren Style anzugeben.

// Beispiel: ..\Kapitel 23\TypedStyle
<Window ... >
<StackPanel>
<Button>Button1</Button>
<Button>Button2</Button>
<Button>Button3</Button>
</StackPanel>
</Window>

Hier noch der XAML-Code in der Datei App.xaml:

<Application ...>
<Application.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Height" Value="35" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>

Listing 23.17 Typisierter Style

Den benutzerdefinierten Standard-Style ausblenden

Möchten Sie, dass eine Komponente nicht von der unter TargetType angegebenen Style-Definition profitiert, legen Sie eine leere Style-Definition an, die als Dummy dient. Diesen Style geben Sie in der Style-Eigenschaft der betreffenden Komponente an, die dann in der Standarddarstellung angezeigt wird:

<Style x:Key="DummyStyle" />
[...]
<Button Style="DummyStyle" ... />

Listing 23.18 Anlegen eines Dummy-Styles


Rheinwerk Computing - Zum Seitenanfang

23.4.3 Erweitern von StylesZur nächsten ÜberschriftZur vorigen Überschrift

Styles lassen sich ähnlich dem Prinzip der Vererbung erweitern. Dabei erbt ein Style die bestehenden Setter-Objekte eines anderen Styles. Die Beziehung des erweiterten Styles zu einem Basis-Style wird mit der Eigenschaft BasedOn der Klasse Style erstellt.

Bereits definierte Eigenschaftswerte können bei diesem Verfahren auch im Bedarfsfall überschrieben werden. Haben Sie im Basis-Style TargetType angegeben, müssen Sie im abgeleiteten Stil ebenfalls eine TargetType-Angabe machen. Diese muss denselben oder einen davon abgeleiteten Typ beschreiben. Im folgenden Beispielprogramm wird das gezeigt.

// Beispiel: ..\Kapitel 23\BasedOnSample
<Window...>
<Window.Resources>
<Style x:Key="Style1" TargetType="{x:Type Button}">
<Setter Property="Button.Height" Value="35" />
<Setter Property="Button.FontSize" Value="18" />
<Setter Property="Button.Margin" Value="10" />
<Setter Property="Button.Background">
<Setter.Value>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="LightCyan" />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="Style2" TargetType="{x:Type Button}"
BasedOn="{StaticResource Style1}">

<Setter Property="Button.FontFamily" Value="Courier New" />
<Setter Property="Button.FontSize" Value="12" />
</Style>
</Window.Resources>
<StackPanel>
<Button Style="{StaticResource Style2}">Button1</Button>
<Button Style="{StaticResource Style1}">Button2</Button>
<Button Style="{StaticResource Style2}">Button3</Button>
</StackPanel>
</Window>

Listing 23.19 Erweitern eines Styles mit »BasedOn«

In diesem Beispiel werden zwei Styles im Resources-Abschnitt des Fensters definiert. Der zuerst aufgeführte Stil Style1 legt neben der Höhe des Steuerelements dessen Schriftfarbe, den Randabstand und die Hintergrunddarstellung fest. Der zweite Style, Style2, übernimmt die Vorgaben des ersten Styles. Dabei wird die Vorgabe des Basis-Styles hinsichtlich der Schriftgröße geändert. Zusätzlich definiert Style2 auch eine andere Schriftart.

Abbildung

Abbildung 23.5 Ausgabe des Beispielprogramms »BasedOnSample«

Abbildung 23.5 zeigt die Ausgabe des Beispiels. Der Effekt des Überschreibens der Schriftgröße der oberen und der unteren Schaltfläche ist hier deutlich zu erkennen.


Rheinwerk Computing - Zum Seitenanfang

23.4.4 EventSetterZur vorigen Überschrift

Bei der Verwendung von Styles steht Ihnen neben Setter auch das Objekt EventSetter zur Verfügung. Mit EventSetter können Sie den Elementen, die den Style benutzen, einen Ereignishandler für ein bestimmtes Ereignis zuordnen. Bei den Ereignissen muss es sich um Routed Events handeln. Die Definition eines EventSetters lautet wie folgt:

<Style>
<EventSetter Event="..." Handler="..." />
</Style>

Dem Attribut Event wird das Ereignis genannt, dem Attribut Handler der entsprechende Ereignishandler. Registrieren Sie sowohl im Style als auch im XAML-Code der Komponente einen Ereignishandler, werden beide ausgeführt. Dabei kommt es immer zuerst zu der Ausführung des Ereignishandlers, der in der Komponente direkt angegeben ist.

Im folgenden Beispiel enthält ein StackPanel zwei ListBoxen sowie zwei in einem zweiten StackPanel horizontal ausgerichtete TextBoxen. Die Listboxen sind an einen typisierten Style gebunden, in dem das Ereignis SelectionChanged mit einem Ereignishandler verknüpft wird. Das gleiche Ereignis wird im XAML-Code der unteren ListBox zudem mit einem weiteren Ereignishandler verknüpft. Der den beiden ListBoxen gemeinsame Ereignishandler schreibt den Inhalt des selektierten Elements in die linke TextBox, der zusätzliche Ereignishandler der unteren ListBox darüber hinaus in die rechte TextBox.

// Beispiel: ..\Kapitel 23\EventSetterSample
<Window ...>
<Window.Resources>
<Style TargetType="ListBox">
<Setter Property="Margin" Value="10" />
<EventSetter Event="SelectionChanged"
Handler="listbox1_SelectionChanged" />

</Style>
</Window.Resources>
<StackPanel>
<ListBox Background="AntiqueWhite" Name="listbox1">
<ListBoxItem>Australien</ListBoxItem>
<ListBoxItem>Thailand</ListBoxItem>
<ListBoxItem>Seychellen</ListBoxItem>
</ListBox>
<ListBox Background="LightSkyBlue" Name="listbox2"
SelectionChanged="listbox2_SelectionChanged" >
<ListBoxItem>Hamburg</ListBoxItem>
<ListBoxItem>München</ListBoxItem>
<ListBoxItem>Berlin</ListBoxItem>
</ListBox>
<StackPanel Orientation="Horizontal">
<TextBox Width="120" Margin="10" Name="txtLinks"
Background="AliceBlue">...</TextBox>
<TextBox Width="120" Margin="10" Name="txtRechts"
Background="AliceBlue">...</TextBox>
</StackPanel>
</StackPanel>
</Window>

Listing 23.20 Definition eines EventSetters

Der Code in der Code-Behind-Datei enthält die beiden Ereignishandler mit dem folgenden Code:

public partial class MainWindow : Window {
private void listbox1_SelectionChanged(...) {
ListBox listbox = sender as ListBox;
txtLinks.Text = ((ListBoxItem)listbox.SelectedItem).Content.ToString();
}
private void listbox2_SelectionChanged(...) {
ListBox listbox = sender as ListBox;
txtRechts.Text = ((ListBoxItem)listbox.SelectedItem).Content.ToString();
}
}

Listing 23.21 C#-Code des Beispielprogramms »EventSetterSample«



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual C# 2012

Visual C# 2012
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: C/C++






 C/C++


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
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.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern