Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Fesselspiele Data Binding in WPF und Silverlight

Ähnliche Präsentationen


Präsentation zum Thema: "Fesselspiele Data Binding in WPF und Silverlight"—  Präsentation transkript:

1 Fesselspiele Data Binding in WPF und Silverlight
Rainer Stropek cubido business solutions gmbh Fesselspiele Data Binding in WPF und Silverlight

2 Ziele Grundlagen von Data Binding in WPF und Silverlight
Erklärung von Data Binding Szenarien anhand von typischen Anwendungsfällen Hinweise auf Unterschiede bei Data Binding zwischen WPF und Silverlight Rainer Stropek, cubido business solutions gmbh

3 Einfaches Data Binding mit und ohne Dependency Properties
Beispiel 1 Einfaches Data Binding mit und ohne Dependency Properties Rainer Stropek, cubido business solutions gmbh

4 Grundlagen Rainer Stropek, cubido business solutions gmbh
public class Competitor { public string FirstName { get; set; } public string LastName { get; set; } } .property instance string FirstName { .get instance string MyApp.Competitor::get_FirstName() .set instance void MyApp.Competitor::set_FirstName(string) } Rainer Stropek, cubido business solutions gmbh

5 Grundlagen Erstellen eines Bindings
{Binding…} Markup Extension Binding Klasse {StaticResource…} Markup Extension zum Zugriff auf Ressourcen Rainer Stropek, cubido business solutions gmbh

6 Einfaches Data Binding
<Window.Resources> <local:Competitor x:Key="MyCompetitor" FirstName="Benjamin" LastName="Raich" /> </Window.Resources> <StackPanel> <TextBox Text="{Binding Source={StaticResource MyCompetitor}, Path=FirstName}" x:Name="FirstNameTextBox" /> <TextBox Text="{Binding Source={StaticResource MyCompetitor}, Path=LastName}" x:Name="LastNameTextBox" /> <StackPanel Orientation="Horizontal"> <TextBlock Text="Competitor:" /> <TextBlock Text="{Binding ElementName=FirstNameTextBox, Path=Text}" /> <TextBlock Text="{Binding ElementName=LastNameTextBox, Path=Text}" /> </StackPanel> <Button Click="Button_Click">Show Competitor</Button> <Button Click="Button_Click_1">Change Competitor</Button> Rainer Stropek, cubido business solutions gmbh

7 Grundlagen Rainer Stropek, cubido business solutions gmbh

8 Grundlagen Geschäftsobjekt Hermann Rainer TextBox TextBlock
Text wird im Code verändert Geschäftsobjekt Änderung des Properties wird nicht erkannt! Hermann Rainer TextBox TextBlock Geschäftsobjekt Hermann Hermann Rainer Hermann TextBox TextBlock Rainer Hermann Rainer Hermann Text wird verändert Rainer Stropek, cubido business solutions gmbh

9 Grundlagen Lösungen des Problems: Dependency Property
Implementieren von INotifyPropertyChanged Rainer Stropek, cubido business solutions gmbh

10 Dependency Property Rainer Stropek, cubido business solutions gmbh
public class Competitor : DependencyObject { public string FirstName get { return (string)GetValue(FirstNameProperty); } set { SetValue(FirstNameProperty, value); } } public static readonly DependencyProperty FirstNameProperty = DependencyProperty.Register("FirstName", typeof(string), typeof(Competitor), new UIPropertyMetadata(String.Empty)); public string LastName get { return (string)GetValue(LastNameProperty); } set { SetValue(LastNameProperty, value); } public static readonly DependencyProperty LastNameProperty = DependencyProperty.Register("LastName", typeof(string), Rainer Stropek, cubido business solutions gmbh

11 WPF übernimmt Verwaltung der Propertywerte
Grundlagen WPF übernimmt Verwaltung der Propertywerte Rainer Stropek, cubido business solutions gmbh

12 Grundlagen Nahezu alle Properties in WPF sind als Dependency Properties implementiert Rainer Stropek, cubido business solutions gmbh

13 Grundlagen Rainer Stropek, cubido business solutions gmbh

14 Animationsbeispiel Rainer Stropek, cubido business solutions gmbh
<Page xmlns=" xmlns:x=" <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Canvas Grid.Row="0"> <Image Canvas.Top="0" Canvas.Left="0" Width="500" Source="..\Schillerfalter.jpg"/> Source="..\Schmetterling.jpg"> <Image.OpacityMask> <LinearGradientBrush> <GradientStop x:Name="OpacityTransparent" Color="#FF000000" Offset="1" /> <GradientStop x:Name="OpacityNonTransparent" Color="# " </LinearGradientBrush> </Image.OpacityMask> </Image> </Canvas> <Button Grid.Row="1"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="OpacityTransparent" Storyboard.TargetProperty="Offset" From="1" To="0" Duration="0:0:2"/> <DoubleAnimation Storyboard.TargetName="OpacityNonTransparent" From="1" To="0" Duration="0:0:2" BeginTime="0:0:0.5"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Button.Triggers> Next Picture </Button> </Grid> </Page> Rainer Stropek, cubido business solutions gmbh

15 Grundlagen Rainer Stropek, cubido business solutions gmbh

16 Einfaches Data Binding
Tipp: DataContext statt Source oder ElementName! public MyWindow() { InitializeComponent(); this.DataContext = new Competitor { FirstName = "Benjamin", LastName = "Raich" }; } <StackPanel> <TextBox Text="{Binding Path=FirstName}" x:Name="FirstNameTextBox" /> <TextBox Text="{Binding Path=LastName}" x:Name="LastNameTextBox" /> <StackPanel Orientation="Horizontal"> <TextBlock Text="Competitor:" /> <TextBlock Text="{Binding Path=FirstName}" /> <TextBlock Text="{Binding Path=LastName}" /> </StackPanel> <Button Click="Button_Click">Show Competitor</Button> <Button Click="Button_Click_1">Change Competitor</Button> Rainer Stropek, cubido business solutions gmbh

17 Data Binding und Collections
Beispiel 2 Data Binding und Collections Rainer Stropek, cubido business solutions gmbh

18 ItemsControl Klasse Binden der Collection an das Property ItemsSource
Tipp: Steuern Sie das Aussehen der einzelnen Items über ein Data Template! Rainer Stropek, cubido business solutions gmbh

19 Binden an ItemsSource Rainer Stropek, cubido business solutions gmbh
public MyWindow() { InitializeComponent(); this.DataContext = new List<Competitor>() { new Competitor() { FirstName = "Hermann", LastName = "Mayer" }, { FirstName = "Benjamin", LastName = "Raich" } }; } Template Binding <ComboBox ItemsSource="{Binding}"> <ComboBox.ItemTemplate> <DataTemplate DataType="{x:Type local:Competitor}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Competitor:" /> <TextBlock Text="{Binding Path=FirstName}" /> <TextBlock Text="{Binding Path=LastName}" /> </StackPanel> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox> Rainer Stropek, cubido business solutions gmbh

20 ComboBox und ListBox nutzen gleiches Template
Binden an ItemsSource <Window.Resources> <DataTemplate DataType="{x:Type local:Competitor}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="Competitor:" /> <TextBlock Text="{Binding Path=FirstName}" /> <TextBlock Text="{Binding Path=LastName}" /> </StackPanel> </DataTemplate> </Window.Resources> <StackPanel> <ComboBox ItemsSource="{Binding}" /> <ListBox ItemsSource="{Binding}" /> Tipp: Legen Sie Data Templates zentral in den Ressourcen ab (Window.Resources oder App.xaml) ComboBox und ListBox nutzen gleiches Template Rainer Stropek, cubido business solutions gmbh

21 Binden an ItemsSource Collection Hermann, Mario Hermann ListBox
Element wird im Code hinzugefügt Collection Änderung der Collection wird nicht erkannt! Hermann, Mario Hermann ListBox Hermann Implementiert INotifyCollectionChanged public MyWindow() { InitializeComponent(); this.DataContext = new ObservableCollection<Competitor>() { new Competitor() { FirstName = "Hermann", LastName = "Mayer" }, { FirstName = "Benjamin", LastName = "Raich" } }; } Rainer Stropek, cubido business solutions gmbh

22 Data Binding und Linq (Entity Framework)
Beispiel 3 Data Binding und Linq (Entity Framework) Rainer Stropek, cubido business solutions gmbh

23 Beispielanwendung Rainer Stropek, cubido business solutions gmbh

24 Hands-on Lab Create a new WPF Application named SkiResults
Add Folder Data Add Entity Model SkiEventModel in Folder Data Model Namespace is SkiResults.Data Rainer Stropek, cubido business solutions gmbh

25 Linq und Data Binding Competitor System.Data. Objects. DataClasses
Linq-Klassen sind für Nutzung mit Data Binding vorbereitet EntityObject StructuralObject INotifyPropertyChanged Rainer Stropek, cubido business solutions gmbh

26 Hands-on Lab Basis-Grid zum Window hinzufügen
<Grid Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ComboBox Name="EventComboBox" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="0,0,0,10" /> <Button Name="SaveButton" Content="Save" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" Margin="0,10,0,0"> </Button> </Grid> Rainer Stropek, cubido business solutions gmbh

27 Hands-on Lab Data Template in App.xaml definieren
<DataTemplate DataType="{x:Type data:Event}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=EventName}" /> <TextBlock Text=" (" /> <TextBlock Text="{Binding Path=Date}" /> <TextBlock Text=")" /> </StackPanel> </DataTemplate> Rainer Stropek, cubido business solutions gmbh

28 Linq und Data Binding private SkiEventEntities Context { get; set; } public Window1() { InitializeComponent(); this.Context = new SkiEventEntities(); this.DataContext = this.Context.Event.Include("Competitor"). OrderBy(e => e.EventName); } Linq-Query wird direkt an ComboBox gebunden <ComboBox Name="EventComboBox" ItemsSource="{Binding}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="0,0,0,10" /> Tipp: Immer Geschäftsobjekte binden, nie Umweg über Strings gehen! Rainer Stropek, cubido business solutions gmbh

29 Master-Detail Bindings
Beispiel 4 Master-Detail Bindings Rainer Stropek, cubido business solutions gmbh

30 Master-Detail Binding
Selektion = Filter für untere Liste Aktuelle Auswahl = Filter Rainer Stropek, cubido business solutions gmbh

31 Hands-on Lab Data Template in App.xaml definieren
<DataTemplate DataType="{x:Type data:Competitor}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Bib}" /> <TextBlock Text=". " /> <TextBlock Text="{Binding Path=Firstname}" /> <TextBlock Text=" " /> <TextBlock Text="{Binding Path=Lastname}" /> </StackPanel> </DataTemplate> Rainer Stropek, cubido business solutions gmbh

32 Master-Detail Binding
Tipp: Mit UpdateSourceTrigger Zeitpunkt der Aktualisierung des Bindings steuern {Binding …, UpdateSourceTrigger=PropertyChanged} <ComboBox Name="EventComboBox" ItemsSource="{Binding}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Margin="0,0,0,10" IsSynchronizedWithCurrentItem="True" /> <ListBox Name="CompetitorListBox" ItemsSource="{Binding Path=Competitor}" Grid.Column="0" Grid.Row="1" Margin="0,0,10,0" IsSynchronizedWithCurrentItem="True" /> Rainer Stropek, cubido business solutions gmbh

33 Hands-on Lab Rainer Stropek, cubido business solutions gmbh
<Grid Grid.Column="1" Grid.Row="1" DataContext="{Binding Path=Competitor}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Grid.Column="0" Grid.Row="0" Text="Bib" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=Bib, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="1" Text="Fis code" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=FisCode, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="2" Text="Firstname" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Firstname, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="3" Text="Lastname" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Path=Lastname, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="4" Text="Year of birth" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="4" Text="{Binding Path=YearOfBirth, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="5" Text="Nation" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="5" Text="{Binding Path=Nation, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="6" Text="Ski" Margin="0,0,10,0" /> <TextBox Grid.Column="1" Grid.Row="6" Text="{Binding Path=Ski, Mode=TwoWay}" /> <TextBlock Grid.Column="0" Grid.Row="7" Text="Total time" Margin="0,0,10,0" /> <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7" Text="{Binding Path=TotalTime, Mode=TwoWay}" /> </Grid> Rainer Stropek, cubido business solutions gmbh

34 Änderungen in DB zurückschreiben
Beispiel 5 Änderungen in DB zurückschreiben Rainer Stropek, cubido business solutions gmbh

35 Master-Detail Binding
protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); this.SaveButton.Click += new RoutedEventHandler(this.SaveButton_Click); } private void SaveButton_Click(object sender, RoutedEventArgs e) this.entities.SaveChanges(); Alles andere erledigt Data Binding! Rainer Stropek, cubido business solutions gmbh

36 Beispiel 6 Converter Rainer Stropek, cubido business solutions gmbh

37 Formatieren oder Umwandeln von Daten im Binding
Standardverhalten: ToString() Rainer Stropek, cubido business solutions gmbh

38 Hands-on Lab Neuen Ordner Converter anlegen
TimeToStringConverter in Projekt erstellen Kopieren von 010 – TimeToStringConverter TimeToStringConverter in App.xaml anlegen Rainer Stropek, cubido business solutions gmbh

39 Converter Rainer Stropek, cubido business solutions gmbh
public class TimeToStringConverter : IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { … } public object ConvertBack(object value, System.Type targetType, } <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7" Text="{Binding Path=TotalTime, Mode=TwoWay, Converter={StaticResource TimeToStringConverter}}" /> Rainer Stropek, cubido business solutions gmbh

40 Gültigkeitsprüfungen
Beispiel 7 Gültigkeitsprüfungen Rainer Stropek, cubido business solutions gmbh

41 Hands-on Lab Neuen Ordner Converter anlegen
TimeToStringConverter in Projekt erweitern Kopieren von TimeToStringConverter with Validation TextBox um Validierung erweitern Textbaustein dafür verwenden Rainer Stropek, cubido business solutions gmbh

42 Tipp: Converter und Gültigkeitsprüfung in einer Klasse zusammenfassen
public class TimeToStringConverter : ValidationRule, IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { … } public object ConvertBack(object value, System.Type targetType, public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { … } } Tipp: Converter und Gültigkeitsprüfung in einer Klasse zusammenfassen <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7"> <TextBox.Text> <Binding Path="TotalTime" Mode="TwoWay" Converter="{StaticResource TimeToStringConverter}"> <Binding.ValidationRules> <ExceptionValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> Rainer Stropek, cubido business solutions gmbh

43 Tipp: Schreibweise kann drastisch verkürzt werden!
Gültigkeitsprüfung Tipp: Schreibweise kann drastisch verkürzt werden! <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7"> <TextBox.Text> <Binding Path="TotalTime" Mode="TwoWay" Converter="{StaticResource TimeToStringConverter}"> <Binding.ValidationRules> <ExceptionValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7"> <TextBox.Text> <Binding Path="TotalTime" Mode="TwoWay" Converter="{StaticResource TimeToStringConverter}“ ValidatesOnExceptions="True" /> </TextBox.Text> </TextBox> <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7" Text="{Binding Path=TotalTime, Mode=TwoWay, Converter={StaticResource TimeToStringConverter}, ValidatesOnExceptions=True}" /> Rainer Stropek, cubido business solutions gmbh

44 Button bleibt trotz Validierungsfehler aktiv
Gültigkeitsprüfung Button bleibt trotz Validierungsfehler aktiv Rainer Stropek, cubido business solutions gmbh

45 Gültigkeitsprüfung public class IsEnabledConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { … } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, } Tipp: Als Multi-Value Converter implementieren, um mehrere Quell-Controls zu unterstützen <Button Name="SaveButton" Content="Save" Grid.Column="0" Grid.ColumnSpan="2“ Grid.Row="2" Margin="0,10,0,0"> <Button.IsEnabled> <MultiBinding Converter="{StaticResource IsEnabledConverter}"> <Binding ElementName="TotalTimeTextBox" Path="(Validation.Errors).Count" /> <!-- Here you can enter additional validations --> </MultiBinding> </Button.IsEnabled> </Button> Rainer Stropek, cubido business solutions gmbh

46 Data Binding über Control-Grenzen hinweg
Beispiel 8 Data Binding über Control-Grenzen hinweg Rainer Stropek, cubido business solutions gmbh

47 Hands-on Lab Detailgrid in eigenes User Control ausgliedern
DataContext in User Control entfernen Namespace in Main Window setzen User Control statt Detailgrid einfügen Validierung bei Save-Button auskommentieren (dafür müsste etwas mehr gemacht werden) Rainer Stropek, cubido business solutions gmbh

48 Data Binding und User Controls
<Window x:Class="SkiResults.Window1" xmlns=" xmlns:x=" xmlns:local="clr-namespace:SkiResults" Title="Window1" Height="500" Width="500"> <local:Details x:Name="DetailsForm" Grid.Column="1" Grid.Row="1" DataContext="{Binding Path=Competitor}" /> </Window> Tipp: Auch bei User Controls mit Data Context arbeiten; wird auch in diesem Fall vererbt! Rainer Stropek, cubido business solutions gmbh

49 Data Binding Unterschiede Silverlight und WPF
Data Binding in Silverlight funktioniert grundsätzlich so wie in WPF Viele Einschränkungen IsSynchronizedWithCurrentItem gibt es nicht Dependency Properties alleine reichen nicht für automatisches Update; INotifyPropertyChanged muss implementiert werden Viele, viele weitere Kleinigkeiten Vorsicht mit der Performance! Rainer Stropek, cubido business solutions gmbh

50 Was wir nicht behandelt haben…
Bindings in Control Templates RelativeSource Bindings Anpassung des Fehlerhinweises bei Validierung Rainer Stropek, cubido business solutions gmbh

51 Lust auf mehr? Bücher Entwickler Akademie
WPF und XAML Programmierhandbuch XAML Kurz & Schnell Entwickler Akademie C# Fundamentals C# 3.5 Upgrade Datenorientierte Anwendungen mit WPF und Silverlight Rainer Stropek, cubido business solutions gmbh

52 Fragen an r.stropek@cubido.at
Vielen Dank für‘s Kommen! Fragen an Rainer Stropek, cubido business solutions gmbh


Herunterladen ppt "Fesselspiele Data Binding in WPF und Silverlight"

Ähnliche Präsentationen


Google-Anzeigen