7. XAML & WPF - Binding Lists

  • View

  • Download

Embed Size (px)


Binding Lists in WPFTelerik Software Academy: http://academy.telerik.com/school-academy/meetings/details/2012/02/02/desktop-applications-csharp-wpfThe website and all video materials are in Bulgarian.Complex Binding in WPFAccessing the "SelectedItem"Using DisplayMemberPath and ValueMemberPathUsing Look-up BindingsUsing Data TemplatesSorting, Filtering and Grouping Items from a Collection View Data Source ProvidersObjectRelationalXMLMaster-detail BindingHierarchical Binding

Text of 7. XAML & WPF - Binding Lists

  • 1. Binding Lists in WPFDoncho MinkovTechnical Trainerhttp://www.minkov.itTelerik Software Academyacademy.telerik.com

2. Table of Contents1. Complex Binding in WPF Accessing the "SelectedItem" Using DisplayMemberPath and ValueMemberPath2. Using Look-up Bindings3. Using Data Templates4. Sorting, Filtering and Grouping Items from a Collection View2 3. Table of Contents (2)7. Data Source Providers Object Relational XML8. Master-detail Binding9. Hierarchical Binding3 4. Complex Data BindingBinding to a Collection of Items 5. Complex Binding Binding to a list data source is exactly the same way as if we were binding to a single object data source// Create an alias for a generic type so that we// can create a list of Person objects in XAMLclass People : List { } 5 6. Complex Binding (2)Name: Each TextBox can be bound to a property from only a single Person object In this example the TextBox will be bound to the first item in the collection ( i.e. "Tom")6 7. Complex Data Binding Live Demo 8. Accessing the"Current Item" 9. Accessing the "Current Item" The text box properties can be bound to only a single object at a time The binding engine is giving them the current item in the list of objects 9 10. Accessing the "Current Item" (3) Collection view in WPF A mediator between the data bound controland the collection of items Accessed through CollectionViewSource The job of the collection view is to provide services on top of the data Control of the current item Sorting Filtering Grouping 10 11. Accessing the "Current Item" (2) Getting the current item of bound collection: public partial class MainWindow : Window { private void birthdayButton_Click(object sender, RoutedEventArgs e) { People people = (People)this.FindResource("Family"); ICollectionView view = CollectionViewSource.GetDefaultView(people); Person person = (Person)view.CurrentItem; ++person.Age; MessageBox.Show(person.Age.ToString()); } }11 12. Navigating Between Items We can change which item is current Using the MoveCurrentTo() methods of the ICollectionView interfaceICollectionView GetFamilyView(){People people =(People)this.FindResource("Family");return CollectionViewSource.GetDefaultView(people);}private void buttonBack_Click(object sender,RoutedEventArgs e){ ICollectionView view = GetFamilyView(); view.MoveCurrentToPrevious(); if (view.IsCurrentBeforeFirst) view.MoveCurrentToFirst();}12 13. Navigating Between Items Live Demo 14. Binding List ControlsDisplayMemberPath and SelectedValuePath 15. Binding List Controls List controlslike ListBox and ComboBox display multiple items at a time Can be bound to a collection in theDataContext Can keep track of the current item When binding the DisplayMemberPathspecifies the property to be displayed The SelectedValuePath specifies the property to be used as selected value (some ID)15 16. DisplayMemberPath If we want to show every object of the Person class and display one of its properties The ListBox class provides theDisplayMemberPath property16 17. SelectedValuePath The ItemsControl class provides a path to describe the selected value of a piece of data Data which is often used when the selection changes or an item is double-clicked private void ListBoxPeople_SelectionChanged( object sender, SelectionChangedEventArgs e) {int index = ListBoxPerson.SelectedIndex;if (index < 0) { return; }Person item = (Person) ListBoxPerson.SelectedItem;int value = (int) ListBoxPerson.SelectedValue; } 17 18. DisplayMemberPath andSelectedValuePathLive Demo 19. Using Look-up Bindings 20. Using Look-up Bindings We want to providea UI that maps numbers to their textual representation in English We must construct a NamedAge type for use in populating a look-up tablepublic class NamedAge{public string NameForAge { get; set; }public int AgeId { get; set; }}class NamedAges : List { }20 21. Using Look-up Bindings (2) Populate the table for looking up The final step is the bit of binding that tells the ComboBox control where to get the currently selected value 21 22. Using Look-up BindingsLive Demo 23. Using Data Templates 24. Using Data Templates Data templates allowdisplaying more than one property from a custom class A data template is a tree of elements to expand in a particular context For example, for each Person object, you might like to be able to concatenate the name and age together This is a logical template that looks like this Name (age:Age)24 25. Using Data Templates (2) To define this template for items in the ListBox, we create a DataTemplate element(age:)25 26. Using Data Templates (2) The ListBox control has an ItemTemplate property Accepts an instance of the DataTemplate class The ListBox shows all the items in the collection26 27. Sorting Items 28. Sorting Items The view allows us to do a number of things to the data before its displayed Including changing the order in which the datais shown The simplest way to sortis by manipulating the SortDescriptions property of the view Also we can provide the view with a customsorting by implementing IComparer 28 29. Sorting Items (2) Sorting items view in WPF:private void buttonSort_Click(object sender, RoutedEventArgs e){ ICollectionView view = GetFamilyView(); if (view.SortDescriptions.Count == 0) {view.SortDescriptions.Add(new SortDescription("Name",ListSortDirection.Ascending));view.SortDescriptions.Add(new SortDescription("Age",ListSortDirection.Descending)); } else view.SortDescriptions.Clear();} 29 30. Sorting Items Live Demo 31. Filtering 32. Filtering If we want to filter the objects from the view by some criteria We need to feed the view an implementation of the Predicate delegate Takes a single object parameter and returns aBooleanprivate void buttonFilter_Click(object sender,RoutedEventArgs e){ICollectionView view = GetFamilyView();// the example continues 32 33. Filtering (2)if (view.Filter == null){view.Filter = delegate(object item){return ((Person)item).Age >= 25;};}else { view.Filter = null; } }// The result is: 33 34. Grouping 35. Grouping To set up grouping Establish the groups you would like to use Manipulating the GroupDescriptions collectionon your viewif (view.GroupDescriptions.Count == 0){ view.GroupDescriptions.Add( new PropertyGroupDescription("Age"));}else{ view.GroupDescriptions.Clear();}35 36. Grouping (2) The PropertyGroupDescription object Takes the name of the property you would like to use for grouping GroupStyle Collection of group visualization related information 36 37. Filtering and GroupingLive Demo 38. Declarative Sortingand Grouping 39. Declarative Sorting and Grouping Bring in the System.ComponentModel and System.Windows.Data namespacesxmlns:compModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"xmlns:data="clr-namespace:System.Windows.Data;assembly=PresentationFramework"> Create SortDescription andPropertyGroupDescription objects Then create a CollectionViewSourceobject, which sorts and groups the data Exposes an ICollectionView implementation39 40. Declarative Sorting and Grouping (2) 40 41. Declarative Sortingand GroupingLive Demo 42. Data Source Providers 43. Object Data Provider Data Providersare wrappers around existing data models (relational data, XML, ) Used to simplify data binding with DB or XML WPF works with two data source providers ObjectDataProvider XmlDataProvider Both derive from DataSourceProvider Data source providers create a layer of indirection for any kind of operation 43 44. Object Data Provider Example Load a set of Person from some sourcepublic class Person : INotifyPropertyChanged { }public class People : ObservableCollection {}public class RemotePeopleLoader{public People LoadPeople(){ // Load people from somewhere People people = new People( ); return people;} } LoadPeople method will load people however it also returns that data for binding44 45. Object Data Provider Example (2) Create the RemotePeopleLoader and call the LoadPeople method in XAML file ... ObjectType specifies the type of the class to create The MethodName specifies the name of the method to call to retrieve the data45 46. Binding to Relational Data We create a database with one table "People" Using Solution Explorer add LINQ-SQL mappings Drag the People table from the Database Explorer Add an instance ofDataClassesPeopleDataContext in .xaml.csDataClassesPeopleDataContext dataContextPeople =new DataClassesPeopleDataContext(); 46 47. Binding to Relational Data (2) Binding to relational data declaratively ...47 48. Binding to Relational Data (3) Adding new records tothe database People newPerson = new People(); newPerson.PersonName = TextBoxAdd.Text; dataContexPeople.Peoples.InsertOnSubmit(newPerson); Committing the changes to databasedataContexPeople.SubmitChanges(); 48 49. Binding to Relational DataLive Demo 50. XML Data Source Provider WPF also supports binding to XML data We can bind to it using the XmlDataProvider 50 51. XML Data Source Provider (2) Use of the XmlDataProvider with a relative URL that points to the family.xml Using namespace prefixes in the XAML makes it possible to construct the XPath statement51 52. XML Data Source Provider (3) In the XML data bindingwe use XmlDocument and XmlElement For updating and accessing values, use the XmlElement.SetAttribute method Sorting or grouping isalso supported, but paths are preceded by @ (e.g., @Age) void birthdayButton_Click(object sender, RoutedEventArgs e) { ICollectionView view = GetFamilyView( ); XmlElement person = (XmlElement)view.CurrentItem; // the example continues52 53. XML Data Source Provider (4)person.SetAttribute("Age", (int.Parse(person.Attributes["Age"].Value) + 1).ToString( ));MessageBox.Show(string.Format("Happy Birthday, {0}, age {1}!",person.Attributes["Name"].Value,person.Attributes["Age"].Value),"Birthday");}void groupButton_Click(object sender, RoutedEve