Complex Data Binding
-
Upload
doncho-minkov -
Category
Business
-
view
1.026 -
download
1
Transcript of Complex Data Binding
Binding Lists in WPFBinding Lists in WPF
Doncho MinkovDoncho Minkov
Telerik School Telerik School AcademyAcademyhttp://schoolacademy.telerik.com
Technical TrainerTechnical Trainerhttp://www.minkov.it
Table of ContentsTable of Contents
1.1. Complex Binding in WPFComplex Binding in WPF Accessing the "Accessing the "SelectedItemSelectedItem"" Using Using DisplayMemberPathDisplayMemberPath and and
ValueMemberPathValueMemberPath
2.2. Using Using Look-upLook-up Bindings Bindings
3.3. Using Data TemplatesUsing Data Templates
4.4. Sorting, Filtering and Grouping Sorting, Filtering and Grouping Items from a Collection View Items from a Collection View
2
Table of Contents (2)Table of Contents (2)
7.7. Data Source ProvidersData Source Providers ObjectObject RelationalRelational XMLXML
8.8. Master-detail BindingMaster-detail Binding
9.9. Hierarchical BindingHierarchical Binding
3
Complex Data Complex Data BindingBindingBinding to a Collection of ItemsBinding to a Collection of Items
Complex Complex BBindinginding Binding to a list data source is Binding to a list data source is
exactly the same way as if we were exactly the same way as if we were binding to a single object data binding to a single object data sourcesource
5
// Create an alias for a generic type so that // Create an alias for a generic type so that wewe// can create a list of Person objects in // can create a list of Person objects in XAMLXAMLclass People : List<Person> { }class People : List<Person> { }<!-- Declaring a collection in XAML --> <!-- Declaring a collection in XAML --> <local:People x:Key="Family"><local:People x:Key="Family"> <local:Person Name="Tom" Age="11" /><local:Person Name="Tom" Age="11" /> <local:Person Name="John" Age="12" /><local:Person Name="John" Age="12" /> <local:Person Name="Melissa" Age="38" /><local:Person Name="Melissa" Age="38" /></local:People></local:People>
Complex Complex BBindinginding (2) (2)
EachEach TextBoxTextBox can be bound to a property can be bound to a property from only a single from only a single PersonPerson objectobject In this example the In this example the TextBoxTextBox will be bound will be bound
to the first item in the collection ( i.e. to the first item in the collection ( i.e. "Tom")"Tom")
6
<Grid DataContext="{StaticResource Family}"><Grid DataContext="{StaticResource Family}"> … … <TextBlock …>Name:</TextBlock><TextBlock …>Name:</TextBlock> <TextBox Text="{Binding Path=Name}" … /><TextBox Text="{Binding Path=Name}" … /> <TextBox Text="{Binding Path=Age}"<TextBox Text="{Binding Path=Age}" Foreground="{Binding Path=Age, Converter=…}"Foreground="{Binding Path=Age, Converter=…}" … …/>/>
Complex Data Complex Data BindingBinding
Live DemoLive Demo
Accessing Accessing the "Current the "Current
Item"Item"
Accessing the "Current Accessing the "Current Item"Item"
The text box properties can be The text box properties can be bound to only a single object at a bound to only a single object at a timetime
The binding engine is giving them The binding engine is giving them the current item in the list of the current item in the list of objectsobjects
9
Accessing the "Current Accessing the "Current Item" (3)Item" (3)
Collection viewCollection view in WPF in WPF A mediator between the data bound A mediator between the data bound
control and the collection of itemscontrol and the collection of items Accessed through Accessed through CollectionViewSourceCollectionViewSource
The job of the collection view is to The job of the collection view is to provide services on top of the dataprovide services on top of the data Control of the current itemControl of the current item SortingSorting FilteringFiltering GroupingGrouping 10
Accessing the "Current Accessing the "Current Item" (2)Item" (2)
Getting the current item of bound Getting the current item of bound collection:collection:
11
public partial class MainWindow : Window {public partial class MainWindow : Window { … … private void birthdayButton_Click(object sender,private void birthdayButton_Click(object sender, RoutedEventArgs e)RoutedEventArgs e) {{ People people = People people = (People)this.FindResource("Family");(People)this.FindResource("Family"); ICollectionView view =ICollectionView view = CollectionViewSource.GetDefaultView(people);CollectionViewSource.GetDefaultView(people); Person person = (Person)Person person = (Person)view.CurrentItemview.CurrentItem;; ++person.Age;++person.Age; MessageBox.Show(person.Age.ToString());MessageBox.Show(person.Age.ToString()); }}}}
Navigating Between Navigating Between ItemsItems
We can change which item is We can change which item is current current Using the Using the MoveCurrentTo(…)MoveCurrentTo(…) methods methods
of the of the ICollectionViewICollectionView interface interface
12
ICollectionView GetFamilyView()ICollectionView GetFamilyView(){{ People people People people =(People)this.FindResource("Family");=(People)this.FindResource("Family"); return return CollectionViewSource.GetDefaultView(people);CollectionViewSource.GetDefaultView(people);}}private void buttonBack_Click(object sender,private void buttonBack_Click(object sender, RoutedEventArgs e)RoutedEventArgs e){{ ICollectionView view = GetFamilyView();ICollectionView view = GetFamilyView(); view.MoveCurrentToPrevious();view.MoveCurrentToPrevious(); if (view.IsCurrentBeforeFirst) if (view.IsCurrentBeforeFirst) view.MoveCurrentToFirst();view.MoveCurrentToFirst();}}
Navigating Between Navigating Between ItemsItemsLive DemoLive Demo
Binding List ControlsBinding List ControlsDisplayMemberPathDisplayMemberPath and and
SelectedValuePathSelectedValuePath
Binding List ControlsBinding List Controls List controls like List controls like ListBoxListBox and and ComboBoxComboBox
display multiple items at a timedisplay multiple items at a time Can be bound to a collection in the Can be bound to a collection in the DataContextDataContext
Can keep track of the current itemCan keep track of the current item
When binding the When binding the DisplayMemberPathDisplayMemberPath specifies the property to be displayedspecifies the property to be displayed
The The SelectedValuePathSelectedValuePath specifies the specifies the property to be used as selected value property to be used as selected value (some ID)(some ID)
15
DisplayMemberPathDisplayMemberPath
If we want to show every object of If we want to show every object of the the PersonPerson class and display one of class and display one of its propertiesits properties TThe he ListBoxListBox class class provides the provides the DisplayMemberPathDisplayMemberPath property property
16
<ListBox ItemsSource="{Binding}"<ListBox ItemsSource="{Binding}" DisplayMemberPath="Name"DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True"IsSynchronizedWithCurrentItem="True"/>/> <!--The result is--><!--The result is-->
SelectedValuePathSelectedValuePath The The ItemsControlItemsControl class provides a class provides a
path to describe the selected value path to describe the selected value of a piece of dataof a piece of data
Data which is often used when the Data which is often used when the selection changes or an item is selection changes or an item is double-clickeddouble-clicked
17
<ListBox Name="ListBoxPeople" <ListBox Name="ListBoxPeople" ItemsSource="{Binding}"ItemsSource="{Binding}" DisplayMemberPath="Name" DisplayMemberPath="Name" SelectedValuePath="Age" />SelectedValuePath="Age" />
private void ListBoxPeople_SelectionChanged(private void ListBoxPeople_SelectionChanged( object sender, SelectionChangedEventArgs e)object sender, SelectionChangedEventArgs e){{ int index = ListBoxPerson.SelectedIndex;int index = ListBoxPerson.SelectedIndex; if (index < 0) { return; }if (index < 0) { return; } Person item = (Person) Person item = (Person) ListBoxPerson.SelectedItem;ListBoxPerson.SelectedItem; int value = (int) ListBoxPerson.SelectedValue; int value = (int) ListBoxPerson.SelectedValue; ……}}
DisplayMemberPathDisplayMemberPath and and
SelectedValuePathSelectedValuePathLive DemoLive Demo
Using Look-up Using Look-up BindingsBindings
Using Look-up BindingsUsing Look-up Bindings We want to provide a UI that maps We want to provide a UI that maps
numbers to their textual numbers to their textual representation in Englishrepresentation in English We must construct a We must construct a NamedAgeNamedAge type type
for use in for use in populatpopulating a look-up tableing a look-up table
20
public class NamedAgepublic class NamedAge{{ public string NameForAge { get; set; }public string NameForAge { get; set; } public int AgeId { get; set; }public int AgeId { get; set; }}}
class NamedAges : List<NamedAge> { }class NamedAges : List<NamedAge> { }
Using Look-up Bindings Using Look-up Bindings (2)(2)
Populate the table for looking upPopulate the table for looking up
The final step is the bit of binding The final step is the bit of binding that tells the that tells the ComboBoxComboBox control control where to get the currently where to get the currently selected valueselected value
21
<local:NamedAges x:Key="NamedAgeLookup"><local:NamedAges x:Key="NamedAgeLookup"> <local:NamedAge NameForAge="zero" AgeId="0" /><local:NamedAge NameForAge="zero" AgeId="0" /> <local:NamedAge NameForAge="one" AgeId="1" /><local:NamedAge NameForAge="one" AgeId="1" /></local:NamedAges></local:NamedAges>
<ComboBox Name="ComboBoxNumbers" ItemsSource=<ComboBox Name="ComboBoxNumbers" ItemsSource= "{Binding Source={StaticResource "{Binding Source={StaticResource NamedAgeLookup}}"NamedAgeLookup}}" DisplayMemberPath="NameForAge"DisplayMemberPath="NameForAge" SelectedValuePath="AgeId"SelectedValuePath="AgeId" SelectedValue="{Binding Path=Age}" />SelectedValue="{Binding Path=Age}" />
Using Look-up Using Look-up BindingsBindingsLive DemoLive Demo
Using Data Using Data TemplatesTemplates
Using Data TemplatesUsing Data Templates Data templates Data templates allow displaying more allow displaying more
than one property from a custom classthan one property from a custom class A data template is a tree of elements to A data template is a tree of elements to
expand in a particular contextexpand in a particular context For example, for each For example, for each PersonPerson object, object,
you might like to be able to you might like to be able to concatenate the concatenate the namename and and ageage together together
This is a logical template that looks like This is a logical template that looks like thisthis NameName (age:Age)(age:Age)
24
Using Data Templates Using Data Templates (2)(2)
To define this template for items in To define this template for items in the the ListBoxListBox, we create a , we create a DataTemplateDataTemplate element element
25
<ListBox ItemsSource="{Binding}"><ListBox ItemsSource="{Binding}"> <ListBox.ItemTemplate><ListBox.ItemTemplate> <DataTemplate><DataTemplate> <TextBlock><TextBlock> <TextBlock Text="{Binding Path=Name}" /><TextBlock Text="{Binding Path=Name}" /> (age: (age: <TextBlock Text="{Binding Path=Age}"<TextBlock Text="{Binding Path=Age}" Foreground="{Binding Path=Age,Foreground="{Binding Path=Age, Converter={StaticResource Converter={StaticResource ageConverter}}" />)ageConverter}}" />) </TextBlock></TextBlock> </DataTemplate></DataTemplate> </ListBox.ItemTemplate></ListBox.ItemTemplate></ListBox></ListBox>
Using Data Templates Using Data Templates (2)(2)
The The ListBoxListBox control has an control has an ItemTemplateItemTemplate property property Accepts an instance of the Accepts an instance of the DataTemplateDataTemplate class class
The The ListBoxListBox shows all the items in shows all the items in the collectionthe collection
26
Sorting ItemsSorting Items
Sorting ItemsSorting Items
The view allows us to do a number The view allows us to do a number of things to the data before it’s of things to the data before it’s displayeddisplayed Including changing the order in Including changing the order in
which which the data is shownthe data is shown The simplest way to sort is by The simplest way to sort is by
manipulating the manipulating the SortDescriptionsSortDescriptions property of the viewproperty of the view AlsoAlso wewe cancan provideprovide the view with a the view with a
custom sorting by implementing custom sorting by implementing IComparerIComparer 28
Sorting Items (2)Sorting Items (2) Sorting items view in WPF:Sorting items view in WPF:
29
private void buttonSort_Clickprivate void buttonSort_Click (object sender, RoutedEventArgs e) (object sender, RoutedEventArgs e) {{ ICollectionView view = GetFamilyView();ICollectionView view = GetFamilyView(); if (view.SortDescriptions.Count == 0)if (view.SortDescriptions.Count == 0) {{ view.SortDescriptions.Add(view.SortDescriptions.Add( new SortDescription("Name",new SortDescription("Name", ListSortDirection.Ascending));ListSortDirection.Ascending)); view.SortDescriptions.Add(view.SortDescriptions.Add( new SortDescription("Age",new SortDescription("Age", ListSortDirection.Descending));ListSortDirection.Descending)); }} elseelse view.SortDescriptions.Clear();view.SortDescriptions.Clear();}}
Sorting ItemsSorting ItemsLive DemoLive Demo
FilteringFiltering
FilteringFiltering
If we want to filter the objects from If we want to filter the objects from the view by some criteriathe view by some criteria
We need to feed the view an We need to feed the view an implementation of the implementation of the Predicate<object>Predicate<object> delegate delegate Takes a single object parameter and Takes a single object parameter and
returns a returns a BooleanBoolean
32
private void buttonFilter_Click(object sender,private void buttonFilter_Click(object sender, RoutedEventArgs e)RoutedEventArgs e){{ ICollectionView view = GetFamilyView(); ICollectionView view = GetFamilyView();
// the example continues// the example continues
Filtering (2)Filtering (2)
33
if (view.Filter == null) if (view.Filter == null) {{ view.Filter = delegate(object item)view.Filter = delegate(object item) {{ return ((Person)item).Age >= 25;return ((Person)item).Age >= 25; };};}}else { view.Filter = null; } } else { view.Filter = null; } } // The result is:// The result is:
GroupingGrouping
GroupingGrouping To set up groupingTo set up grouping
Establish the groups you would Establish the groups you would like like to useto use Manipulating the Manipulating the GroupDescriptionsGroupDescriptions
collection on your viewcollection on your view
35
if (view.GroupDescriptions.Count == 0) if (view.GroupDescriptions.Count == 0) {{ view.GroupDescriptions.Add(view.GroupDescriptions.Add( new PropertyGroupDescription("Age"));new PropertyGroupDescription("Age"));}}else else {{ view.GroupDescriptions.Clear();view.GroupDescriptions.Clear();}}
Grouping (2)Grouping (2) The The PropertyGroupDescriptionPropertyGroupDescription
objectobject Takes the name of the property you Takes the name of the property you
would like to use for groupingwould like to use for grouping GroupStyleGroupStyle
Collection of group visualization Collection of group visualization related informationrelated information
36
<ListBox … ItemsSource="{Binding}" ><ListBox … ItemsSource="{Binding}" > <ListBox.GroupStyle><ListBox.GroupStyle> <x:Static Member="GroupStyle.Default" /><x:Static Member="GroupStyle.Default" /> </ListBox.GroupStyle></ListBox.GroupStyle></ListBox></ListBox>
Filtering and Filtering and GroupingGrouping
Live DemoLive Demo
Declarative Declarative Sorting and Sorting and
GroupingGrouping
Declarative Sorting and Declarative Sorting and GroupingGrouping
Bring in the Bring in the System.ComponentModelSystem.ComponentModel and and System.Windows.DataSystem.Windows.Data namespaces namespaces
Create Create SortDescriptionSortDescription and and PropertyGroupDescriptionPropertyGroupDescription objects objects
Then create a Then create a CollectionViewSourceCollectionViewSource object, which sorts and groups the dataobject, which sorts and groups the data EExposes an xposes an ICollectionViewICollectionView
implementationimplementation39
xmlns:compModel="clr-xmlns:compModel="clr-namespace:System.ComponentModel; namespace:System.ComponentModel; assembly=WindowsBase" assembly=WindowsBase" xmlns:data="clr-xmlns:data="clr-namespace:System.Windows.Data;assembly=namespace:System.Windows.Data;assembly=PresentationFramework">PresentationFramework">
Declarative Declarative Sorting and Sorting and
Grouping (2)Grouping (2)
40
<CollectionViewSource x:Key="SortedGroupedFamily"<CollectionViewSource x:Key="SortedGroupedFamily" Source="{StaticResource Family}">Source="{StaticResource Family}"> <CollectionViewSource.SortDescriptions><CollectionViewSource.SortDescriptions> <compModel:SortDescription <compModel:SortDescription PropertyName="Name"PropertyName="Name" Direction="Ascending" />Direction="Ascending" /> <compModel:SortDescription PropertyName="Age"<compModel:SortDescription PropertyName="Age" Direction="Descending" />Direction="Descending" /> </CollectionViewSource.SortDescriptions></CollectionViewSource.SortDescriptions> <CollectionViewSource.GroupDescriptions><CollectionViewSource.GroupDescriptions> <data:PropertyGroupDescription<data:PropertyGroupDescription PropertyName="Age"PropertyName="Age" Converter="{StaticResource Converter="{StaticResource ageConverter}" />ageConverter}" /> <data:PropertyGroupDescription<data:PropertyGroupDescription PropertyName="Age" />PropertyName="Age" /> </CollectionViewSource.GroupDescriptions> </CollectionViewSource.GroupDescriptions> </CollectionViewSource></CollectionViewSource>
Declarative Declarative Sorting and Sorting and
GroupingGroupingLive DemoLive Demo
Data Data Source Source
ProvidersProviders
Object Data ProviderObject Data Provider Data Providers are wrappers around Data Providers are wrappers around
existing data models (relational data, existing data models (relational data, XML, …)XML, …) Used to simplify data binding with DB or Used to simplify data binding with DB or
XMLXML WPF works with two data source WPF works with two data source
providersproviders ObjectDataProviderObjectDataProvider XmlDataProviderXmlDataProvider
Both derive from Both derive from DataSourceProviderDataSourceProvider Data source providers create a layer of Data source providers create a layer of
indirection for any kind of operationindirection for any kind of operation43
Object Data ProviderObject Data Provider – – ExampleExample
Load a set of Load a set of PersonPerson from some source from some source
LoadPeopleLoadPeople method will load people method will load people however it also returns that data for however it also returns that data for bindingbinding
44
public class Person : INotifyPropertyChanged public class Person : INotifyPropertyChanged { … }{ … }
public class People : public class People : ObservableCollection<Person> {}ObservableCollection<Person> {}
public class RemotePeopleLoader public class RemotePeopleLoader {{ public People LoadPeople()public People LoadPeople() {{ // Load people from somewhere// Load people from somewhere People people = new People( ); …People people = new People( ); … return people;return people; } …} …}}
Object Data ProviderObject Data Provider – – Example (2)Example (2)
Create the Create the RemotePeopleLoaderRemotePeopleLoader and call and call the the LoadPeopleLoadPeople method in XAML file method in XAML file
ObjectTypeObjectType specifies the type of the specifies the type of the class to createclass to create
The The MethodNameMethodName specifies the name of specifies the name of the method to call to retrieve the datathe method to call to retrieve the data
45
<Window.Resources> ...<Window.Resources> ... <ObjectDataProvider x:Key="Family"<ObjectDataProvider x:Key="Family" ObjectType="{x:Type ObjectType="{x:Type local:RemotePeopleLoader}"local:RemotePeopleLoader}" MethodName="LoadPeople" />MethodName="LoadPeople" /></Window.Resources></Window.Resources>
Binding to Relational Binding to Relational DataData
We create a database with one table We create a database with one table ""PeoplePeople""
Using Solution Explorer add LINQ-SQL Using Solution Explorer add LINQ-SQL mappingsmappings
Drag the People table from the Database Drag the People table from the Database ExplorerExplorer
Add an instance of Add an instance of DataClassesPeopleDataContextDataClassesPeopleDataContext in in .xaml.cs.xaml.cs
46
DataClassesPeopleDataContext dataContextPeople = DataClassesPeopleDataContext dataContextPeople = new DataClassesPeopleDataContext();new DataClassesPeopleDataContext();
Binding to Relational Binding to Relational Data (2)Data (2)
Binding to relational data Binding to relational data declarativelydeclaratively
47
<Window.Resources><Window.Resources> <DataTemplate <DataTemplate x:Key="DataTemplatePersonName">x:Key="DataTemplatePersonName"> <TextBlock Text="{Binding <TextBlock Text="{Binding Path=PersonName}"/>Path=PersonName}"/> </DataTemplate></DataTemplate></Window.Resources></Window.Resources> ......<ListBox Name="ListBoxPeople" ItemTemplate=<ListBox Name="ListBoxPeople" ItemTemplate= "{StaticResource "{StaticResource DataTemplatePersonName }"/>DataTemplatePersonName }"/>
Binding to Relational Binding to Relational Data (3)Data (3)
Adding Adding nnew ew rrecords to the ecords to the ddatabaseatabase
Committing the Committing the cchanges to hanges to ddatabaseatabase
48
People newPerson = new People();People newPerson = new People();newPerson.PersonName = TextBoxAdd.Text; newPerson.PersonName = TextBoxAdd.Text; dataContexPeople.Peoples.InsertOnSubmit(newPersdataContexPeople.Peoples.InsertOnSubmit(newPerson);on);
dataContexPeople.SubmitChanges();dataContexPeople.SubmitChanges();
Binding to Relational Binding to Relational DataDataLive DemoLive Demo
XML Data Source XML Data Source ProviderProvider
WPF also supports binding to XML WPF also supports binding to XML datadata
We can bind to it using the We can bind to it using the XmlDataProviderXmlDataProvider
50
<Window.Resources><Window.Resources> <XmlDataProvider<XmlDataProvider x:Key="Family"x:Key="Family" Source="family.xml"Source="family.xml" XPath="/sb:Family/sb:Person">XPath="/sb:Family/sb:Person"> <XmlDataProvider.XmlNamespaceManager><XmlDataProvider.XmlNamespaceManager> <XmlNamespaceMappingCollection><XmlNamespaceMappingCollection> <XmlNamespaceMapping Prefix="sb" <XmlNamespaceMapping Prefix="sb" Uri="http://sellsbrothers.com" />Uri="http://sellsbrothers.com" /> </XmlNamespaceMappingCollection></XmlNamespaceMappingCollection> </XmlDataProvider.XmlNamespaceManager></XmlDataProvider.XmlNamespaceManager> </XmlDataProvider> <!--the example </XmlDataProvider> <!--the example continues-->continues-->
XML Data Source XML Data Source Provider (2)Provider (2)
Use of the Use of the XmlDataProviderXmlDataProvider with a relative with a relative URL that points to the URL that points to the family.xmlfamily.xml
Using namespace prefixes in the XAML Using namespace prefixes in the XAML makes it possible to construct the makes it possible to construct the XPathXPath statement statement
51
… …<StackPanel Orientation="Horizontal"><StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding XPath=@Name}" /><TextBlock Text="{Binding XPath=@Name}" /> <TextBlock Text=" (age: " /><TextBlock Text=" (age: " /> <TextBlock Text="{Binding XPath=@Age}"<TextBlock Text="{Binding XPath=@Age}" Foreground="{Binding XPath=@Age,Foreground="{Binding XPath=@Age, Converter= {StaticResource ageConverter}}" />Converter= {StaticResource ageConverter}}" /> <TextBlock Text=")" /><TextBlock Text=")" /></StackPanel></StackPanel>……
XML Data Source XML Data Source Provider (3)Provider (3)
In the XML data binding we use In the XML data binding we use XmlDocumentXmlDocument and and XmlElementXmlElement
For updating and accessing values, For updating and accessing values, use the use the XmlElementXmlElement..SetAttributeSetAttribute methodmethod
Sorting or grouping is also Sorting or grouping is also supported, but paths are preceded supported, but paths are preceded by by @@ (e.g., (e.g., @Age@Age))
52
void birthdayButton_Click(object sender,void birthdayButton_Click(object sender, RoutedEventArgs e)RoutedEventArgs e){{ ICollectionView view = GetFamilyView( );ICollectionView view = GetFamilyView( ); XmlElement person = (XmlElement)view.CurrentItem;XmlElement person = (XmlElement)view.CurrentItem;
// the example continues// the example continues
XML Data Source XML Data Source Provider (4)Provider (4)
53
person.SetAttribute("Age", (int.Parse(person.SetAttribute("Age", (int.Parse( person.Attributes["Age"].Value) + person.Attributes["Age"].Value) + 1).ToString( )); 1).ToString( )); MessageBox.Show(MessageBox.Show( string.Format("Happy Birthday, {0}, age {1}!",string.Format("Happy Birthday, {0}, age {1}!", person.Attributes["Name"].Value,person.Attributes["Name"].Value, person.Attributes["Age"].Value),person.Attributes["Age"].Value), "Birthday");"Birthday");}}……void groupButton_Click(object sender, void groupButton_Click(object sender, RoutedEventArgs e) {RoutedEventArgs e) { ICollectionView view = GetFamilyView( );ICollectionView view = GetFamilyView( ); if( view.GroupDescriptions.Count == 0 ) if( view.GroupDescriptions.Count == 0 ) {{ view.GroupDescriptions.Add(newview.GroupDescriptions.Add(new PropertyGroupDescription("@Age"));PropertyGroupDescription("@Age")); }} else { view.GroupDescriptions.Clear(); }else { view.GroupDescriptions.Clear(); }}}
XML Data Source XML Data Source ProviderProviderLive DemoLive Demo
Master-Detail Master-Detail BindingBinding
Master-Details BindingMaster-Details Binding Master-details binding Master-details binding means to bind means to bind
two related liststwo related lists Selecting a row in the first list shows its Selecting a row in the first list shows its
detail rows in the second listdetail rows in the second list You need to have a You need to have a parentparent data object data object
that provides a collection of related that provides a collection of related childchild objects objects
Master-details bindingMaster-details binding is a form of is a form of filteringfiltering Where the selection in the master list Where the selection in the master list
acts as filtering parameter for the acts as filtering parameter for the associated detail listassociated detail list 56
Master-Details Binding Master-Details Binding (2)(2)
In previous example we have families In previous example we have families and peopleand people
Instances of Families, Family, People, Instances of Families, Family, People, and Person looked like thisand Person looked like this
57
The The FamiliesFamilies collection is collection is the master datathe master data It is holding instances It is holding instances
of the of the FamilyFamily class class Each of which holds Each of which holds
members property of members property of type type PeoplePeople
Which holds the detail Which holds the detail PersonPerson
Master-Details Binding – Master-Details Binding – ExampleExample
Declaring master-detail data:Declaring master-detail data:
58
<Window.Resources><Window.Resources> <local:Families x:Key="Families"><local:Families x:Key="Families"> <local:Family FamilyName="Piyandetata"><local:Family FamilyName="Piyandetata"> <local:Family.Members><local:Family.Members> <local:People><local:People> <local:Person Name="Joro Vodkata" <local:Person Name="Joro Vodkata" Age="21" />Age="21" /> … … </local:People></local:People> </local:Family.Members></local:Family.Members> </local:Family></local:Family> <local:Family FamilyName="Addams"><local:Family FamilyName="Addams"> <local:Family.Members><local:Family.Members> <local:People><local:People> <local:Person Name="Uncle Fester" <local:Person Name="Uncle Fester" Age="135" />Age="135" /> … … </local:Families></local:Families></Window.Resources></Window.Resources>
Master-Details Binding – Master-Details Binding –
Example (2)Example (2) Binding to master Binding to master FamilyFamily data: data:
59
<Window.Resources><Window.Resources> <local:Families <local:Families x:Key="Families">…</local:Families>x:Key="Families">…</local:Families></Window.Resources></Window.Resources><Grid DataContext="{StaticResource Families}"><Grid DataContext="{StaticResource Families}"> … … <!-- Families Column --><!-- Families Column --> <TextBlock Grid.Row="0"<TextBlock Grid.Row="0" Grid.Column="0">Families:</TextBlock>Grid.Column="0">Families:</TextBlock> <ListBox Grid.Row="1" Grid.Column="0"<ListBox Grid.Row="1" Grid.Column="0" IsSynchronizedWithCurrentItem="True"IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}">ItemsSource="{Binding}"> <ListBox.ItemTemplate><ListBox.ItemTemplate> <DataTemplate><DataTemplate> <TextBlock Text="{Binding <TextBlock Text="{Binding Path=FamilyName}" />Path=FamilyName}" /> </DataTemplate></DataTemplate> </ListBox.ItemTemplate></ListBox.ItemTemplate> </ListBox></ListBox>
Master-Details Binding Master-Details Binding – –
Example (3)Example (3) Binding to detail Binding to detail PersonPerson data: data:
60
<Grid DataContext="{StaticResource Families}"> ...<Grid DataContext="{StaticResource Families}"> ... … … <!-- Members Column --><!-- Members Column --> <StackPanel Grid.Row="0" Grid.Column="1" <StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal">Orientation="Horizontal"> <TextBlock Text="{Binding Path=FamilyName}" /><TextBlock Text="{Binding Path=FamilyName}" /> <TextBlock Text=" Family Members:" /><TextBlock Text=" Family Members:" /> </StackPanel></StackPanel> <ListBox Grid.Row="1" Grid.Column="1"<ListBox Grid.Row="1" Grid.Column="1" IsSynchronizedWithCurrentItem="True"IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=Members}" >ItemsSource="{Binding Path=Members}" > <ListBox.ItemTemplate><ListBox.ItemTemplate> <DataTemplate><DataTemplate> <StackPanel Orientation="Horizontal"><StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}" /><TextBlock Text="{Binding Path=Name}" /> <TextBlock Text=" (age: " /><TextBlock Text=" (age: " /> <TextBlock Text="{Binding Path=Age}" /><TextBlock Text="{Binding Path=Age}" /> <TextBlock Text=" )" /> …<TextBlock Text=" )" /> …
Master-Details Master-Details BindingBinding
Live DemoLive Demo
Hierarchical BindingHierarchical Binding
Hierarchical BindingHierarchical Binding Hierarchical binding Hierarchical binding generally involves generally involves
some number of levels, unknown until some number of levels, unknown until runtimeruntime E.g. a tree of items, each with few child E.g. a tree of items, each with few child
itemsitems Control that can expand itself as Control that can expand itself as
appropriate, like a menu or a tree needs appropriate, like a menu or a tree needs hierarchical bindinghierarchical binding
WPF has built-in support for hierarchical WPF has built-in support for hierarchical binding using a special kind of data binding using a special kind of data templatetemplate Knows both how to display the current level Knows both how to display the current level
of data and where to go for the next levelof data and where to go for the next level63
Hierarchical Binding (2)Hierarchical Binding (2) Binding a Binding a TreeViewTreeView control’s root control’s root
itemitem PProvide a data templaterovide a data template
64
<DataTemplate DataType="{x:Type <DataTemplate DataType="{x:Type local:Family}">local:Family}"> <TextBlock Text="{Binding <TextBlock Text="{Binding Path=FamilyName}" />Path=FamilyName}" /> </DataTemplate></DataTemplate></Window.Resources></Window.Resources>…… <TreeView DataContext="{StaticResource <TreeView DataContext="{StaticResource Families}">Families}"> <TreeViewItem ItemsSource="{Binding}" <TreeViewItem ItemsSource="{Binding}" Header="Families" />Header="Families" /> </TreeView></TreeView>
Hierarchical Binding (3)Hierarchical Binding (3) HierarchicalDataTemplateHierarchicalDataTemplate element element
Provides the Provides the ItemsSourceItemsSource property property so that the tree can keep digging so that the tree can keep digging into the datainto the data
65
<HierarchicalDataTemplate DataType="{x:Type <HierarchicalDataTemplate DataType="{x:Type local:Family}"local:Family}" ItemsSource="{Binding Path=Members}">ItemsSource="{Binding Path=Members}"> <TextBlock Text="{Binding Path=FamilyName}" /><TextBlock Text="{Binding Path=FamilyName}" /></HierarchicalDataTemplate></HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type <HierarchicalDataTemplate DataType="{x:Type local:Person}"local:Person}" ItemsSource="{Binding Path=Traits}">ItemsSource="{Binding Path=Traits}"> <TextBlock><TextBlock> <TextBlock Text="{Binding Path=Name}" /><TextBlock Text="{Binding Path=Name}" /> (age: <TextBlock Text="{Binding Path=Age}" />)(age: <TextBlock Text="{Binding Path=Age}" />) </TextBlock></TextBlock></HierarchicalDataTemplate></HierarchicalDataTemplate>
Binding ListsBinding Lists
Questions?Questions?
http://academy.telerik.com
ExercisesExercises
1.1. Write a program to manage a simple Write a program to manage a simple system with information about towns and system with information about towns and countries. Each country is described by countries. Each country is described by name, language, national flag and list of name, language, national flag and list of towns. Each town is described by name, towns. Each town is described by name, population and country. You should create population and country. You should create navigation over the towns and countries. navigation over the towns and countries. Enable editing the information about Enable editing the information about them. Don't use them. Don't use listlist controlscontrols but only but only text text boxesboxes and simple bindingand simple binding
2.2. Rewrite the previous exercise using Rewrite the previous exercise using list list controlscontrols..
67
Exercises (2)Exercises (2)
3.3. Create a database with two tables – Create a database with two tables – CategoriesCategories and and ProductsProducts. Each category . Each category has category name. Each product has has category name. Each product has category, model number, model name category, model number, model name unit cost, and description. Consider the unit cost, and description. Consider the simple window look like the screenshot simple window look like the screenshot below:below:
68
Design a form to Design a form to view products by view products by ID and bind all ID and bind all controls to their controls to their relevant columns relevant columns from the database from the database tables.tables.
Exercises (3)Exercises (3)
4.4. Using complex data binding create a Using complex data binding create a system, resembling the system from the system, resembling the system from the first exercise (towns and countries). Add to first exercise (towns and countries). Add to the system a set of continents – each the system a set of continents – each country is in one of them. Display data and country is in one of them. Display data and enable navigation. Load and save the data enable navigation. Load and save the data in a XML file. Add sin a XML file. Add sortingorting,, filtering and filtering and grouping grouping functions. Use master-details functions. Use master-details bindings.bindings.
5.5. Rewrite the previous exercise to use Rewrite the previous exercise to use database and LINQ-to-SQL. Ensure all database and LINQ-to-SQL. Ensure all entities can be added / edited / deleted entities can be added / edited / deleted (continents, countries and towns).(continents, countries and towns). 69