430 likes | 571 Views
Fesselspiele. Data Binding in WPF und Silverlight. 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. Beispiel 1.
E N D
Rainer Stropekcubido business solutions gmbh Fesselspiele Data Binding in WPF und Silverlight
Rainer Stropek, cubido business solutions gmbh 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 Beispiel 1 Einfaches Data Binding mit und ohne Dependency Properties
Rainer Stropek, cubido business solutions gmbh Grundlagen public class Competitor { public string FirstName { get; set; } public string LastName { get; set; } } .property instance string FirstName { .get instance stringMyApp.Competitor::get_FirstName() .set instance void MyApp.Competitor::set_FirstName(string) }
Rainer Stropek, cubido business solutions gmbh Grundlagen • Erstellen eines Bindings • {Binding…} Markup Extension • Binding Klasse • {StaticResource…} Markup Extension zum Zugriff auf Ressourcen
Rainer Stropek, cubido business solutions gmbh 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> <StackPanel Orientation="Horizontal"> <Button Click="Button_Click">Show Competitor</Button> <Button Click="Button_Click_1">Change Competitor</Button> </StackPanel> </StackPanel>
Rainer Stropek, cubido business solutions gmbh Grundlagen Text wird im Code verändert Geschäftsobjekt Änderung des Properties wird nicht erkannt! Hermann Rainer TextBox TextBlock Geschäftsobjekt Hermann Hermann Hermann Rainer TextBox TextBlock Hermann Rainer Hermann Rainer Text wird verändert
Rainer Stropek, cubido business solutions gmbh Grundlagen • Lösungen des Problems: • Dependency Property • Implementieren von INotifyPropertyChanged
Rainer Stropek, cubido business solutions gmbh Dependency Property public class Competitor : DependencyObject { public string FirstName { get { return (string)GetValue(FirstNameProperty); } set { SetValue(FirstNameProperty, value); } } public static readonlyDependencyPropertyFirstNameProperty = 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 readonlyDependencyPropertyLastNameProperty = DependencyProperty.Register("LastName", typeof(string), typeof(Competitor), new UIPropertyMetadata(String.Empty)); } }
Rainer Stropek, cubido business solutions gmbh Grundlagen WPF übernimmt Verwaltung derPropertywerte
Rainer Stropek, cubido business solutions gmbh Grundlagen • Nahezu alle Properties in WPF sind als Dependency Properties implementiert
Rainer Stropek, cubido business solutions gmbh 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> <StackPanel Orientation="Horizontal"> <Button Click="Button_Click">Show Competitor</Button> <Button Click="Button_Click_1">Change Competitor</Button> </StackPanel> </StackPanel>
Rainer Stropek, cubido business solutions gmbh Beispiel 2 Data Binding und Collections
Rainer Stropek, cubido business solutions gmbh 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 Binden an ItemsSource public MyWindow() { InitializeComponent(); this.DataContext = new List<Competitor>() { new Competitor() { FirstName = "Hermann", LastName = "Mayer" }, new Competitor() { 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 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}" /> … </StackPanel> Tipp: Legen Sie Data Templates zentral in den Ressourcen ab (Window.Resources oder App.xaml) ComboBoxund ListBox nutzen gleiches Template
Rainer Stropek, cubido business solutions gmbh Binden an ItemsSource 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" }, new Competitor() { FirstName = "Benjamin", LastName = "Raich" } }; }
Rainer Stropek, cubido business solutions gmbh Beispiel 3 Data Binding und Linq(Entity Framework)
Rainer Stropek, cubido business solutions gmbh Beispielanwendung
Rainer Stropek, cubido business solutions gmbh 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 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 ComboBoxgebunden … <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 Beispiel 4 Master-Detail Bindings
Rainer Stropek, cubido business solutions gmbh Master-Detail Binding Selektion = Filter für untere Liste Aktuelle Auswahl = Filter
Rainer Stropek, cubido business solutions gmbh 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 Beispiel 5 Änderungen in DB zurückschreiben
Rainer Stropek, cubido business solutions gmbh 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 Beispiel 6 Converter
Rainer Stropek, cubido business solutions gmbh Formatieren oder Umwandeln von Daten im Binding Standardverhalten: ToString()
Rainer Stropek, cubido business solutions gmbh Converter 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, object parameter, System.Globalization.CultureInfo culture) { … } } … <TextBox Name="TotalTimeTextBox" Grid.Column="1" Grid.Row="7" Text="{Binding Path=TotalTime, Mode=TwoWay, Converter={StaticResource TimeToStringConverter}}" /> …
Rainer Stropek, cubido business solutions gmbh Beispiel 7 Gültigkeitsprüfungen
Rainer Stropek, cubido business solutions gmbh Gültigkeitsprüfung 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, object parameter, System.Globalization.CultureInfo culture) { … } 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 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 Gültigkeitsprüfung Button bleibt trotz Validierungsfehler aktiv
Rainer Stropek, cubido business solutions gmbh 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, System.Globalization.CultureInfo culture) { … } } 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 Beispiel 8 Data Binding über Control-Grenzen hinweg
Rainer Stropek, cubido business solutions gmbh Data Binding und User Controls <Window x:Class="SkiResults.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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 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 Was wir nicht behandelt haben… • Bindings in Control Templates • RelativeSourceBindings • Anpassung des Fehlerhinweises bei Validierung
Rainer Stropek, cubido business solutions gmbh Lust auf mehr? • Bücher • 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 Vielen Dank für‘s Kommen! Fragen anr.stropek@cubido.at