Windows Phone 7 数据绑定与UI 刷新: Displaying Data with Data Binding

 Displaying Data with Data Binding
Change Notification

In order for changes to the source object to propagate to the target, the source must implement the INotifyPropertyChanged interface. INotifyPropertyChanged has the PropertyChanged event, which tells the binding engine that the source has changed so that the binding engine can update the target value.

In the following example, the MyColors class implements the INotifyPropertyChanged interface for OneWay binding.

//  Create a class that implements INotifyPropertyChanged.
public  class MyColors : INotifyPropertyChanged
{
     private SolidColorBrush _Brush1;

     //  Declare the PropertyChanged event.
     public  event PropertyChangedEventHandler PropertyChanged;

     //  Create the property that will be the source of the binding.
     public SolidColorBrush Brush1
    {
         get {  return _Brush1; }
         set
        {
            _Brush1 = value;
             //  Call NotifyPropertyChanged when the source property 
            
//  is updated.
            NotifyPropertyChanged( " Brush1 ");
        }
    }


     //  NotifyPropertyChanged will raise the PropertyChanged event, 
    
//  passing the source property that is being updated.
     public  void NotifyPropertyChanged( string propertyName)
    {
         if (PropertyChanged !=  null)
        {
            PropertyChanged( this
                 new PropertyChangedEventArgs(propertyName));
        }
    }
}

To get change notification for collections bound to an ItemsControl, implement INotifyCollectionChanged in addition to INotifyPropertyChanged. If you implement INotifyCollectionChanged, changes to the collection, such as adding or removing an object, will propagate to the target. To get property change notification for objects in the collection, the objects must implement INotifyPropertyChanged.

Before implementing your own collection, consider using the ObservableCollection(Of T) class, which has a built-in implementation of INotifyCollectionChanged and INotifyPropertyChanged.

In TwoWay bindings, changes to the target automatically update the source, except when binding to the Text property of a TextBox. In this case, the update occurs when the TextBox loses focus.

You can disable automatic source updates and update the source at times of your choosing. For example, you can do this to validate user input from multiple controls before you update the bound data sources.

To disable automatic source updates, set the UpdateSourceTrigger property to Explicit. This setting affects all bindings that use the same Binding object (for example, when using an inherited data context). You must update the source for each binding individually, however. To update a binding, first call the FrameworkElement.GetBindingExpression method of a target element, passing in the target DependencyProperty. You can then use the return value to call the BindingExpression.UpdateSource method. The following example code demonstrates this process.

 
          

A binding source object can be treated either as a single object whose properties contain data or as a collection of objects. For example, you might want to display a list of items, such as monthly credit card bills. To do this, use an ItemsControl and use a DataTemplate to display each item in a collection. For more information on data templates, see How to: Customize Data Display with Data Templates.

 
    
          
            
< Grid.Resources >

       < DataTemplate  x:Name ="dataTemplate" >
   
         < Grid >
           < Grid.ColumnDefinitions >
 
             < ColumnDefinition  />

             < ColumnDefinition  />
           </ Grid.ColumnDefinitions >
< TextBlock  Grid.Column ="0"  
 
  Text
=" {Binding Month, Converter={StaticResource Converter1}} " />

           < TextBlock  Grid.Column ="1"  Text =" {Binding Total} " />    
         </ Grid >
       </ DataTemplate >

     </ Grid.Resources >

     < ItemsControl  x:Name ="IC1"  ItemsSource =" {Binding} "  
      ItemTemplate
=" {StaticResource dataTemplate} " />

You can enumerate over any collection that implements IEnumerable. If you want the target to update the ItemsSource when the collection changes, implement INotifyCollectionChanged. For more information on change notification, see the Change Notification section earlier in this topic.

You can also bind to instances of the CollectionViewSource class, which provides sorting, grouping, filtering, and currency support for other data sources. The CollectionViewSource enables you to display multiple views of data that stay synchronized with user selection changes.

You can also use CollectionViewSource to bind multiple controls to hierarchically-related data. For more information, see How to: Bind to Hierarchical Data and Create a Master/Details View.

The PagedCollectionView class provides another way to apply sorting, grouping, and filtering to another data source. This class also includes paging and editing, and provides a data source for controls such as DataPager.

For information about encapsulating a generic list in an object so that you can bind a control to it, see the first code examples for List(Of T) and Dictionary(Of TKey, TValue).

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace PhoneApp5
{
     public  partial  class MainPage : PhoneApplicationPage, INotifyPropertyChanged
    {
         //  Constructor
         public MainPage()
        {
            InitializeComponent();
        }

         public ObservableCollection<DirectorySource> dataSource;

         protected  override  void OnNavigatedTo(NavigationEventArgs e)
        {
             base.OnNavigatedTo(e);
            UpdateUI();
        }

         private  void UpdateUI()
        {
             if (directoryListBox.ItemsSource ==  null)
            {
                 if (dataSource ==  null)
                {
                    dataSource = GetDataSource();
                }

                directoryListBox.ItemsSource = dataSource;
            }
        }

         private ObservableCollection<DirectorySource> GetDataSource()
        {
            ObservableCollection<DirectorySource> dataSource;
             int i =  0;

             switch (i)
            {
                 case  1: dataSource = GetDataSourceOne();
                     break;
                 case  2: dataSource = GetDataSourceTwo();
                     break;
                 case  3: dataSource = GetDataSourceThreee();
                     break;
                 default: dataSource = GetAllDataSource();
                     break;
            }

             return dataSource;
        }

         private ObservableCollection<DirectorySource> GetDataSourceOne()
        {
             throw  new NotImplementedException();
        }

         private ObservableCollection<DirectorySource> GetDataSourceTwo()
        {
             throw  new NotImplementedException();
        }

         private ObservableCollection<DirectorySource> GetDataSourceThreee()
        {
             throw  new NotImplementedException();
        }

         private ObservableCollection<DirectorySource> GetAllDataSource()
        {
             for ( int i =  1; i <  10; i++)
            {
                DirectorySource directorySource =  new DirectorySource();
                directorySource.DisplayMemo = i.ToString();
                directorySource.DisplayName = i.ToString();
                DataManager.source.Add(directorySource);
            }

            SortSource();       


             return DataManager.source;
        }

         private  void SortSource()
        {
            List<DirectorySource> test = DataManager.source.ToList<DirectorySource>();
            test.Sort();
            DataManager.source =  new ObservableCollection<DirectorySource>(test);

            dataSource = DataManager.source;            
        }


         protected  override  void OnNavigatingFrom(NavigatingCancelEventArgs e)
        {
             base.OnNavigatingFrom(e);
        }

         private  void button1_Click( object sender, RoutedEventArgs e)
        {
            Random rnd1 =  new Random( 0);

            DirectorySource directorySource =  new DirectorySource();
             //  directorySource.DisplayMemo = rnd1.Next().ToString();
            
// directorySource.DisplayName = rnd1.Next().ToString();


            directorySource.DisplayMemo =  " 0 ";
            directorySource.DisplayName =  " 0 ";
            DataManager.source.Add(directorySource);

            SortSource();
        }


         private  void ReSetDataSource()
        {
            directoryListBox.ItemsSource = dataSource;
        }            

         private  void button2_Click( object sender, RoutedEventArgs e)
        {
            DataManager.source[ 1].DisplayMemo =  " 200 ";
            DataManager.source[ 1].DisplayName =  " 200 ";

        }

         #region INotifyPropertyChanged Members

         public  event PropertyChangedEventHandler PropertyChanged;


         #endregion
    }
   
}
< phone:PhoneApplicationPage 
    
x:Class ="PhoneApp5.MainPage"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone
="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell
="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d
="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc
="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable
="d"  d:DesignWidth ="480"  d:DesignHeight ="768"
    FontFamily
=" {StaticResource PhoneFontFamilyNormal} "
    FontSize
=" {StaticResource PhoneFontSizeNormal} "
    Foreground
=" {StaticResource PhoneForegroundBrush} "
    SupportedOrientations
="Portrait"  Orientation ="Portrait"
    shell:SystemTray.IsVisible
="True" >

     <!-- LayoutRoot is the root grid where all page content is placed -->
     < Grid  x:Name ="LayoutRoot"  Background ="Transparent" >
         < Grid.RowDefinitions >
             < RowDefinition  Height ="Auto" />
             < RowDefinition  Height ="*" />
         </ Grid.RowDefinitions >

         <!-- TitlePanel contains the name of the application and page title -->
         < StackPanel  x:Name ="TitlePanel"  Grid.Row ="0"  Margin ="12,17,0,28" >
             < TextBlock  x:Name ="ApplicationTitle"  Text ="MY APPLICATION"  Style =" {StaticResource PhoneTextNormalStyle} " />
             < TextBlock  x:Name ="PageTitle"  Text ="page name"  Margin ="9,-7,0,0"  Style =" {StaticResource PhoneTextTitle1Style} " />
         </ StackPanel >

         <!-- ContentPanel - place additional content here -->
         <!-- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,291">
            <Grid.RowDefinitions>
                <RowDefinition>
                    <RowDefinition.Height>100</RowDefinition.Height>
                </RowDefinition>                
                <RowDefinition>
                    <RowDefinition.Height>100</RowDefinition.Height>
                </RowDefinition>               
               </Grid.RowDefinitions>
               
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1"/>
                <ColumnDefinition Width="169" />
                <ColumnDefinition Width="190" />
                <ColumnDefinition Width="96*" />
            </Grid.ColumnDefinitions>
        </Grid>
-->
         < ListBox  BorderThickness ="0"  Grid.Row ="1"  Name ="directoryListBox"  
                     SelectionMode
="Single"  Margin ="0,0,0,164" >
             < ListBox.ItemTemplate  >
                 < DataTemplate  >
                     < Grid  Margin ="12,0,0,5"   >
                         < Grid.ColumnDefinitions >
                             < ColumnDefinition  Width ="70" ></ ColumnDefinition >
                             < ColumnDefinition ></ ColumnDefinition >
                         </ Grid.ColumnDefinitions >
                         < Grid.RowDefinitions >
                             < RowDefinition  Height ="45" ></ RowDefinition >
                             <!-- <RowDefinition Height="25"></RowDefinition> -->
                         </ Grid.RowDefinitions >
                         <!-- <Image Name="photoImage" Source="{Binding Path=Image}" Width="70"  Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Stretch="UniformToFill" /> -->
                         < TextBlock  Text =" {Binding Path=DisplayName} "  Name ="name"  
                                       Grid.Row
="0"  Grid.Column ="0"  
                                       VerticalAlignment
="Top"  HorizontalAlignment ="Left"                                        
                                       Style
=" {StaticResource PhoneTextLargeStyle} " ></ TextBlock >
                         < TextBlock  Name ="titleDept"  Text =" {Binding Path=DisplayMemo} "  
                                       Grid.Row
="0"  Grid.Column ="1"
                                       VerticalAlignment
="Center"  HorizontalAlignment ="Left"
                                       Style
=" {StaticResource PhoneTextSubtleStyle} "   >
                         </ TextBlock >
                     </ Grid >
                 </ DataTemplate >
             </ ListBox.ItemTemplate >
               
           
         </ ListBox >
         < Button  Content ="Add"  Grid.Row ="1"  Height ="72"  HorizontalAlignment ="Left"  Margin ="32,465,0,0"  Name ="button1"  VerticalAlignment ="Top"  Width ="110"  Click ="button1_Click"   />
         < Button  Content ="Change"  Grid.Row ="1"  Height ="72"  HorizontalAlignment ="Left"  Margin ="148,465,0,0"  Name ="button2"  VerticalAlignment ="Top"  Width ="130"  Click ="button2_Click"   />
     </ Grid >
 
     <!-- Sample code showing usage of ApplicationBar -->
     <!-- <phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>
-->

</ phone:PhoneApplicationPage >
 
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace PhoneApp5
{
     public  static  class DataManager
    {    
         public  static ObservableCollection<DirectorySource> source =  new ObservableCollection<DirectorySource>();     
    }

     public  class DirectorySource : INotifyPropertyChanged, IComparable
    {

         #region INotifyPropertyChanged Members

         public  event PropertyChangedEventHandler PropertyChanged;

         #endregion


         private  string displayName =  string.Empty;
         private  string displayMemo =  string.Empty;

         public DirectorySource()
        {

        }

         public  string DisplayName
        {
             get
            {
                 return  this.displayName;
            }
             set
            {
                 if ( this.displayName != value)
                {
                     this.displayName = value;
                    OnPropertyChanged( " DisplayName ");
                }
            }
        }

         public  string DisplayMemo
        {
             get
            {
                 return  this.displayMemo;
            }
             set
            {
                 if ( this.displayMemo != value)
                {
                     this.displayMemo = value;
                    OnPropertyChanged( " DisplayMemo ");
                }
            }
        }


         protected  void OnPropertyChanged( string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
             if (handler !=  null)
                handler( thisnew PropertyChangedEventArgs(propertyName));
        }

         #region IComparable Members

         public  int CompareTo( object obj)
        {
            DirectorySource test = obj  as DirectorySource;

             return  string.Compare( this.DisplayName, test.DisplayName);
        }

         #endregion
    }
}
Refer to:
1). INotifyCollectionChanged Interface
2): ObservableCollection (Of T ) Class
3): Data Binding
4): Displaying Data with Data Binding

你可能感兴趣的:(windows phone)