GUI-Programmierung 2 - WPF Proseminar Objektorientiertes Programmieren mit.net und C# Alexander Aumann Institut für Informatik Software & Systems Engineering
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 2
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 3
WPF Windows Presentation Foundation Programmierschnittstelle zur Oberflächenerstellung für Windows in.net Nachfolger von WindowsForms Komplett neuartige Umsetzung 4
Vergleich WPF - WindowsForms WindowsForms greift zum Zeichnen von Standard-Kontrollelementen auf die Win32-API (speziell GDI/GDI+) zurück WPF verwendet DirectX um alle Steuerelemente selbst zu zeichnen Hardwarebeschleunigt - Ausnutzung moderner Grafikkarten Einfaches und Umfassendes Anpassen des Aussehens von Steuerelementen möglich XAML zum Definieren umfangreicher Oberflächen komplett ohne C# Code Strikte Trennung von Design und Programmlogik Nachteile: steile Lernkurve, Einarbeitungszeit, WindowsForms ausgereifter 5
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 6
XAML Extensible Application Markup Language Basierend auf XML Sprache zur Definition des Layouts der Oberfläche und des Aussehens der einzelnen Steuerelemente ( Control Templates, Styles) Auch Ressourcenverwaltung in XAML Neues WPF-Projekt enthält App.xaml App.xaml.cs MainWindow.xaml MainWindow.cs 7
XAML Erstes Beispiel MainWindow.xaml <Window x:class="wpfapplication.mainwindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> </Grid> </Window> MainWindow.xaml.cs using System; (...weitere using- Direktiven...) namespace WpfApplication { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } } } 8
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 9
Layouts und Steuerelemente Verfügbare Layout-Container StackPanel WrapPanel DockPanel Grid UniformGrid Canvas Können beliebig geschachtelt werden Standardsteuerelemente ähnlich wie in WindowsForms Allerdings fehlen einige wenige Steuerelemente wie DateTimePicker DataGridView FolderBrowserDialog 10
StackPanel Ordnet Elemente als vertikalen oder horizontalen Stapel an Einzelne Elemente können durch Alignment-Eigenschaften ihre Anordnung im Stapel beeinflussen <StackPanel HorizontalAlignment="Stretch" Margin="3" Name="stackPanel1"> <Label Content="Label oben" Name="label1" /> <Button Content="Button ohne Alignment" Name="button1" /> <Button Content="Button Alignment right" Name="button2" HorizontalAlignment="Right"/> <TextBox Text="Textfeld Alignment Center" Name="textBox1" HorizontalAlignment="Center"/> <Button Content="Button Alignmentleft" Name="button3" HorizontalAlignment="Left"/> </StackPanel> 11
DockPanel Kann Elemente an vier Seiten andocken (z.b. Toolbars) Restlicher Platz geht an übrige Elemente Reihenfolge der Anordnung entscheidend <DockPanel Name="dockPanel1"> <Button Content="oben" Name="button1" DockPanel.Dock="Top"/> <Button Content="links" Name="button2" DockPanel.Dock="Left"/> <Button Content="rechts" Name="button3" DockPanel.Dock="Right"/> <Button Content="unten" Name="button4" DockPanel.Dock="Bottom"/> <Button Content="rest" Name="button5" /> </DockPanel> 12
WrapPanel Ordnet Elemente als Reihe an Bei Platzmangel werden die Elemente in die nächste Reihe geschoben <WrapPanel Name="wrapPanel1"> <Button Content="Hoch" Height="50" Name="button1" /> <Button Content="Zentral" VerticalAlignment="Center" Name="button2" /> <Button Content="Oben" VerticalAlignment="Top" Name="button3" /> <Button Content="Gestreckt" Name="button4" /> <Button Content="Unten" VerticalAlignment="Bottom" Name="button5" /> </WrapPanel> 13
Grid Mächtigster Layoutcontainer Teilt Gebiet in Zeilen und Spalten auf Komponenten werden einer Zelle zugewiesen, können sich aber über mehrere Zeilen und/oder Spalten erstrecken Aufwändige Layouts möglich 14
Grid Beispielanwendung Filmsammlung 15
Grid Beispielanwendung Filmsammlung <Grid Name="gridMain" Margin="3"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="3*"/> </Grid.ColumnDefinitions> <Label Content="Filmsammlung" Name="labelListTitle" HorizontalAlignment="Center" VerticalAlignment="Top"/> <ListBox Name="listBoxFilms" Grid.Row="1" Grid.RowSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MinWidth="30" HorizontalContentAlignment="Stretch" Margin="2"/> <GridSplitter Name="gridSplitter1" Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" HorizontalAlignment="Center" VerticalAlignment="Stretch" Width="5" /> <Label Content="Filmdaten" Name="labelFilmData" Grid.Column="2" Grid.ColumnSpan="4" HorizontalAlignment="Center" VerticalAlignment="Top"/> <Grid Name="gridRight" Grid.Row="1" Grid.Column="2" Margin="2">...[Labels und TextBox- Steuerelemente rechtes Grid]... </Grid> <StackPanel Name="stackPanelButtons" Grid.Column ="2" Grid.ColumnSpan="1" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="2"> <Button /> <Button...> </StackPanel> </Grid> 16
Andere Layouts Uniform Grid Teilt Gebiet in gleich große Zeilen und Spalten auf Canvas Erlaubt starre Anordnung nach Koordinatens 17
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 18
Styles und Control Templates Ermöglichen es dem Designer einer Anwendung bzw. einzelnen Kontrollelementen ein völlig neues Aussehen zu geben in XAML ohne das Element komplett neu zu schreiben die Bedienfunktionalität bleibt erhalten (Button sendet seine Events etc.) Durch sogenannte Trigger auch abhängig von Eigenschaften, die sich dynamisch ändern (z.b. Fokus) und damit auch MouseOver-Effekte möglich 19
Styles ein Beispiel Style um einzelne Eigenschaften von Steuerelementen zu verändern Beispiel: Label mit geänderter Schriftart, -größe und -farbe <Style x:key="labelheaderstyle"> <Style.Setters> <Setter Property="Label.FontSize" Value="14"/> <Setter Property="Label.FontWeight" Value="Bold"/> <Setter Property="Label.FontFamily" Value="TimesNewRoman"/> <Setter Property="Label.Foreground"> <Setter.Value> <LinearGradientBrush > <GradientStop Color="Black" Offset="0"/> <GradientStop Color="Black" Offset="0.66"/> <GradientStop Color="Black" Offset="1"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style.Setters> </Style> 20
Styles Event Trigger Ermöglichen es auf Events zu reagieren und Steuerelementeigenschaften entsprechend zu setzen Beispiel: Schriftfarbe animieren, wenn Mauszeiger über Label <Style>...Setter... <Style.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <ColorAnimation Storyboard.TargetProperty="Foreground.GradientStops[1].Color" To="BurlyWood" Duration="0:0:0.5" AutoReverse="False"/> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave">...rückgängig machen... </EventTrigger> </Style.Triggers> </Style> 21
Style mit Steuerelementen verknüpfen Styles werden im Regelfall zur Fenster- oder Anwendungsklasse als Ressource hinzugefügt (entweder direkt oder durch Einbinden einer Datei) Zwei Möglichkeiten der Verknüpfung: Setzen der Style-Eigenschaft und verbinden mit Ressource <Label Content="Filmdaten" (...) Style="{StaticResource LabelHeaderStyle}"/> Automatisch für alle Steuerelemente eines Typs: Keinen Key für den Style vergeben und TargetType festlegen <Style TargetType="Button"> (...) </Style > 22
Styles und Control Templates Control Templates Elemente sind (intern) aus weiteren Elementen zusammengesetzt Diese Elemente / die Art des Zusammenbaus lassen sich mit Control Templates modifizieren Bieten somit eine mächtige Ergänzung zu Styles 23
Beispiel: ein eigenes Button Control Template <Style TargetType="Button"> <VisualStateManager.VisualStateGroups> <Setter> <VisualStateGroup x:name="commonstates">... <VisualStateGroup.Transitions> </Setter> <Setter Property="Template"> <VisualTransition <Setter.Value> GeneratedDuration="0:0:0.5" /> <ControlTemplate TargetType="Button"> <VisualTransition GeneratedDuration="0" <Border TextBlock.Foreground="{TemplateBinding To="Pressed" /> Foreground}" </VisualStateGroup.Transitions> x:name="border" CornerRadius="8" <VisualState x:name="normal" /> BorderThickness="1"> <VisualState x:name="mouseover"> <Border.BorderBrush>...festlegen, wie der Button...BorderBrush festlegen... aussieht, wenn der Mauszeiger </Border.BorderBrush> darüberliegt... <Border.Background>...Hintergrund festlegen... </VisualState> </Border.Background> <VisualState x:name="pressed"> <VisualStateManager.VisualStateGroups>...festlegen, wie ein gedrückter...siehe rechts...- > Button aussieht... </VisualStateManager.VisualStateGroups> </VisualState> <ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="Center" <VisualState x:name="disabled"> VerticalAlignment="Center"...festlegen, wie deaktivierter RecognizesAccessKey="True" /> Button aussieht... </Border> </VisualState> <ControlTemplate.Triggers> </VisualStateGroup>...auch Trigger können zusätzlich definiert werden... </ControlTemplate.Triggers> </VisualStateManager.VisualStateGroups> </ControlTemplate> </Setter.Value> </Setter> </Style> 24
Ergebnis: Filmsammlung vorher 25
Ergebnis: Filmsammlung nachher 26
Übersicht Einleitung und Unterschiede zu WindowsForms XAML Oberflächendefinitionssprache für WPF Layouts und Steuerelemente Styles und Control Templates DataBinding und Data Templates 27
Data Binding und DataTemplates zuständig für Bindung zwischen Daten und Darstellung (Dependency) Property Binding Eigenschaften eines Elements als Quelle und eines anderen als Ziel Bindung der Schriftgröße eines Elements an die Position einer Scrollleiste Schriftgröße passt sich direkt an, wenn Scrollleiste bewegt wird Bindung einer Farbauswahlliste an die Farbe bestimmter Elemente Bindung an komplexe Datenstrukturen Anbindung einer internen Liste von Filmen an eine ListBox und Füllen der Textfelder, je nachdem welcher Film gewählt ist (siehe folgende Folien) 28
Data Binding 1: Daten bereitstellen Klasse Film mit entsprechenden public properties: Code zum Vernüpfen der ListBox mit der datenseitigen Filmliste class Film { private string fullname; public string FullName { get { return fullname; } set { fullname=value;} } private string shortname; public string ShortName { get { return shortname; } set { shortname=value; } }...restliche Properties... } public partial class MainWindow : Window { DataStore ds; ObservableCollection<Film> films; public MainWindow() { InitializeComponent(); ds = new DataStore(); films = ds.getfilms(); listboxfilms.itemssource = films; } } 29
Data Binding 2: Daten mit Anzeige verknüfpen Text-Property der Textfelder mit entsprechender Film-Property verknüpfen: Data Binding hinzufügen <TextBox Name="textBoxTitleComplete" (...) Text="{Binding Path=FullName}" /> Datenquelle setzen DataContext im Grid setzen => Kinder erben diesen Context als Quelle für ihr Data Binding <Grid Name="gridMain" Margin="3" DataContext= "{Binding ElementName=listBoxFilms, Path=SelectedItem}" > (...) </Grid > 30
Data Binding: Filmsammlung / Stand der Dinge 31
DataTemplates Darstellung eines Filmobjekts Data Templates Wie werden die einzelnen Daten im Kontrollelement dargestellt Beliebiges Layout und Steuerelemente möglich Beispiele Anordnung von Daten in einer Tabellenzelle in einem einzelnen Listenelement nicht nur der Filmtitel, sondern noch ein oder mehrere Zusatzinformationen Dadurch wird die an sich einfache Standardliste nahezu beliebig erweiterbar 32
Data Template: Listenelement Data Template definieren <DataTemplate x:key="filmdatatemplate"> <Border CornerRadius="4" BorderThickness="1" Margin="3"> <Border.BorderBrush> <SolidColorBrush Color="{StaticResource BorderMediumColor}" /> </Border.BorderBrush> <Grid Margin="2"> (...Grid.Row und Grid.Column Definitionen...) <TextBlock Grid.Row="0" FontWeight="Bold" Text="{Binding Path=ShortName}"/> <TextBlock Grid.Row="1" Text="{Binding Path=Directors}" Margin="4, 0, 0, 0" HorizontalAlignment="Left"/> </Grid> </Border> </DataTemplate> Template für die ListBox setzen <ListBox Name="listBoxFilms" ItemTemplate="{StaticResource FilmDataTemplate}" HorizontalContentAlignment="Stretch" (...) /> 33
Endergebnis Filmsammlung mit vorgestellten Styles und Data Bindings 34