⬆️ ⬇️

Create an application for Windows Phone 7 from start to finish. Part 9. Data mapping

Previous part



So you have created a full page for your application. Now you probably want to fill them with various data.



In this part you will learn:

Data binding to user interface



The Fuel Tracker application has three data pages. Data is stored mainly in three classes. The following image shows the pages and related classes.

')

image



To display data, data binding is usually used. Data binding provides the ability to connect a user interface to a data source. When bindings are created and the data source is changed, the user interface elements that are associated with the data source display the changes automatically. Similarly, changes made by the user to the user interface element are reflected in the data source. For example, if a user changes the value in TextBox, the corresponding data source is automatically updated to reflect these changes.



The following XAML code snippet illustrates the syntax used to bind the Text property of a TextBox control to the Name property of the source object.

< TextBox x:Name ="NameTextBox" Text ="{Binding Name, Mode=TwoWay}" /> * This source code was highlighted with Source Code Highlighter .
  1. < TextBox x:Name ="NameTextBox" Text ="{Binding Name, Mode=TwoWay}" /> * This source code was highlighted with Source Code Highlighter .
< TextBox x:Name ="NameTextBox" Text ="{Binding Name, Mode=TwoWay}" /> * This source code was highlighted with Source Code Highlighter .


The following image shows an example of such a binding.



image



Each binding has a Mode property that determines how and when data is updated. OneWay (one-way) binding means that the target (target) user interface element is updated if the source changes. TwoWay (two-way) binding means that both the target and the source are updated if any of them change. If you are using OneWay or TwoWay bindings, then in order for the binding to be notified of changes to the source object, you must implement the INotifyPropertyChanged interface. This interface will be discussed in more detail in the next section, Creating Data Classes.



You specify the source object by setting the DataContext property (data context). If you use the ListBox control, you must specify the source object by setting the ItemsSource property. The following example shows how to set the DataContext property of the CarHeader panel of the source object to be retrieved from the static property.

  1. CarHeader.DataContext = CarDataStore.Car;
* This source code was highlighted with Source Code Highlighter .


The DataContext property allows you to set a standard binding for the entire user interface element, including all its child elements. In some cases, it will be more convenient for you to set the DataContext property for the entire page, and in some cases it will be more convenient to set it separately for each element on the page. Installing a DataContext at each level XAML blocks any installation at a higher level. In addition, you can actually override any DataContext setting for individual bindings by setting the Source property for them.



For example, in the Fuel Tracker application, each page sets the DataContext to a different value. However, on the page level FillupPage DataContext page is overridden for a panel that displays the name of the car and its photo. The following image shows the data context settings for the Fuel Tracker application.



image



Using data binding builder



Visual Studio includes a data binding builder to help you create data bindings in XAML. Although the data binding builder can provide improved performance, it does not support all possible scenarios. For example, it does not support snapping to indexed elements and it does not recognize the bindings created in the code. Thus, in some cases, you will need to specify data bindings manually.



To use the data binding builder :

  1. Select the control for which you want to create a binding.
  2. In the Properties window, find the property to which you want to bind.
  3. At the edge of the left column, click the property marker icon, and then click the Apply Data Binding button.

    The data binding builder opens.
  4. Click on the various panels in the data binding builder to expand the various options.

    The following image shows the data binding builder with the following parameters:
    • Data context: Fillup object
    • Binding path: OdometerReading property
    • Converter: ZeroFormatter
    • Mode: TwoWay
    image

The following XAML snippet shows the code generated by the data binding builder.

  1. < Textbox
  2. Grid Row = "0" Grid . Column = "1"
  3. x: Name = "OdometerTextBox"
  4. Text = "{Binding OdometerReading, Mode = TwoWay, Converter = {StaticResource ZeroFormatter}}"
  5. InputScope = "TelephoneNumber"
  6. MaxLength = "8" />
* This source code was highlighted with Source Code Highlighter .


Note:

When you set the DataContext property in your code, the data binding builder has no idea about the properties available in the data source and cannot help you choose a binding path. However, you can solve this problem by setting the data context at design time. Additional information on how to set up the data context at design time can be found here: Walkthrough: Using the DesignInstance to Bind Data in the Silverlight Designer .



Display data in the list



Displaying a collection of items in the list is one of the main tasks on the phone. In order to display a collection of items in the list using data binding, you need to do the following:

  1. Add ListBox to your application.
  2. Specify the data source for the ListBox by binding the collection to the ItemsSource property.
  3. To customize the appearance of each item in the ListBox, add a data template for the ListBox.
  4. In the data template, bind the ListBox elements to the properties of the element collection.
The following image shows the bindings for the ListBox on the summary page of the Fuel Tracker application.



image



The following XAML code shows how the bindings were specified for the ListBox.

  1. < ListBox ItemContainerStyle = "{StaticResource ListBoxStyle}"
  2. ItemsSource = "{Binding FillupHistory}"
  3. Height = "380" HorizontalAlignment = "Left" Margin = "5.25,0.0"
  4. VerticalAlignment = "Top" Width = "444" >
  5. < ListBox.ItemTemplate >
  6. < DataTemplate >
  7. < StackPanel Orientation = "Horizontal" >
  8. < TextBlock Style = "{StaticResource SummaryStyle}"
  9. Text = "{Binding Date, Converter = {StaticResource StringFormatter}, ConverterParameter = \ {0: d \}}"
  10. Width = "105" TextWrapping = "Wrap" />
  11. < TextBlock Style = "{StaticResource SummaryStyle}"
  12. Text = "{Binding FuelQuantity}" TextWrapping = "Wrap" />
  13. < TextBlock Style = "{StaticResource SummaryStyle}"
  14. Text = "{Binding DistanceDriven}" TextWrapping = "Wrap" />
  15. < TextBlock Style = "{StaticResource SummaryStyle}"
  16. Text = "{Binding PricePerFuelUnit, Converter = {StaticResource StringFormatter}, ConverterParameter = \ {0: c \}, ConverterCulture = en-US}" />
  17. < TextBlock Style = "{StaticResource SummaryStyle}"
  18. Text = "{Binding FuelEfficiency, Converter = {StaticResource StringFormatter}, ConverterParameter = \ {0: F \}}" TextWrapping = "Wrap" />
  19. </ StackPanel >
  20. </ DataTemplate >
  21. </ ListBox.ItemTemplate >
  22. </ Listbox >
* This source code was highlighted with Source Code Highlighter .


In the previous XAML code, the ListBox.ItemsSource property is bound to the Car.FillupHistory property so that each Fillup object in the history collection appears as a separate item in the ListBox. The DataTemplate element defines the appearance of each item and contains several TextBlock elements, each of which is tied to a property of the Fillup class.



This XAML will only work when a Car object is first associated with a page, as shown in the following code from SummaryPage.xaml.cs.

  1. this .DataContext = CarDataStore.Car;
* This source code was highlighted with Source Code Highlighter .


Performance Improvement Tip:

If the scrolling in your ListBox does not seem smooth and responsive, use the following tips:

Difficult binding paths



In addition to the flexibility of setting the DataContext property at any level (which allows you to override settings at a higher level), you can also specify complex binding paths in order to “drill” into link properties such as Car.FillupHistory . For example, the following XAML code from SummaryPage.xaml demonstrates a binding to the Fillup.FuelEfficiency property of the first item in the collection of the history of refills.

  1. < TextBlock Text = "{Binding FillupHistory [0] .FuelEfficiency, Converter = {StaticResource StringFormatter}, ConverterParameter = \ {0: F \}}" />
* This source code was highlighted with Source Code Highlighter .


The following image shows the bindings in SummaryPage.xaml and shows how complex bindings and data templates allow you to bind controls to different properties of different objects, even if they all belong to the same DataContext.



image



The green rectangles on the left Pivot screen show controls that are tied using complex paths. These paths begin with the first element (index 0) in the Car.FillupHistory collection and end with the various properties of the Fillup class. For example, the Current MPG field uses the binding path FillupHistory [0] .FuelEfficiency . If you include the page's DataContext setting in this path, the entire binding path will look like this: CarDataStore.Car.FillupHistory [0] .FuelEfficiency .



Next part

Source: https://habr.com/ru/post/118287/



All Articles