WPF 范例程序之二 – 构建Hello Kitty 专卖店产品演示 – 附源代码下载
范例程序演示界面如下:
1. App.xaml 文件中Application.Resources 节设置应用程序范围资源,如样式、画笔、数据源等等。
范例程序中定义了ObjectDataProvider,将返回PhotoList 集合对象。
<Application.Resources>
<ObjectDataProvider x:Name="PhotosODP" x:Key="Photos" ObjectType="{x:Type sbts:PhotoList}" />
</Application.Resources>
同时,在App.xaml.cs 代码文件中,对上述集合对象进行了初始化操作。
private void Application_Startup(object sender, StartupEventArgs e)
{
Window1 theWindow = new Window1();
theWindow.Show();
ObjectDataProvider dataProvider = this.Resources["Photos"] as ObjectDataProvider;
PhotoList photoList = dataProvider.Data as PhotoList;
theWindow.Photos = photoList;
theWindow.Photos.Path = @"..\..\HelloKitty";
}
2. 数据绑定
WPF支持任何类型的.NET对象作为数据源绑定到WPF对象。对于所有的ItemsControl对象都有一个ItemsSource依赖属性,这是专门为数据绑定而准备的。ItemsSource的类型是IEnumerable,所以对于我们几乎所有的集合类型我们都可以轻易的改变成ItemsSource的源对象。
将上述定义的Application.Resources 应用到ListBox 上,实现Hello Kitty 产品图片的展示。
<ListBox Style="{DynamicResource PhotoListStyle}"
Grid.Row="1"
Grid.ColumnSpan="3"
Name ="PhotoListBox"
Margin="0,0,0,20"
DataContext="{Binding Source={StaticResource Photos}}"
SelectionChanged ="PhotoListSelection"
ItemsSource="{Binding }"
ItemContainerStyle="{DynamicResource PhotoListItem}"
SelectedIndex="0" />
DataContext就是数据上下文对象,它是为了避免多个对象共享一个数据源时重复的对所有对象显式地用binding标记,而把同一个数据源在上下文对象的某个范围内共享,这样当一个绑定没有显式的源对象时,WPF会遍历找到一个非空的DataContext为止。
3. ListBox控件的SelectionChanged 事件。
PhotoListSelection 方法负责读取ListBox 控件当前选择的Item图片,并进一步根据选择的产品图片,创建BitmapFrame 对象,最后绑定到CurrentPhoto1(Image控件)上,显示并放大选择的产品图片。
private void PhotoListSelection(object sender, SelectionChangedEventArgs e)
{
String path = ((sender as ListBox).SelectedItem.ToString());
BitmapSource img = BitmapFrame.Create(new Uri(path));
CurrentPhoto1.Source = img;
}
4. ObservableCollection(T) 类
WPF提供了一个ObservableCollection类,它实现了一个暴露了INotifyPropertyChanged的数据集合。也就是说我们不需要自己对每个单独的数据实现INotifyPropertyChanged结构。Observablecollection表示一个动态数据集合,在添加项、移除项或刷新整个列表时,此集合将提供通知。
在本范例程序中,PhotoList 集合类继承ObservableCollection<ImageFile>,代码如下:
public class PhotoList : ObservableCollection<ImageFile>
在绑定PhotoList类到ListBox之后,只要PhotoList 对象发生了变化,Listbox 的数据也会有相应的变化,也就是是PhotoList集合中的插入或移除操作可以自动更新 UI。
如果你有兴趣,你可以将上述代码调整为List 集合,如下所示:
public class PhotoList : List<ImageFile>
再次运行应用程序,你会发现ListBox 无法正确显示Hello Kitty 产品图片列表了。但是如果你进一步修改Application_Startup方法的代码,如下所示:
private void Application_Startup(object sender, StartupEventArgs e)
{
Window1 theWindow = new Window1();
ObjectDataProvider dataProvider = this.Resources["Photos"] as ObjectDataProvider;
PhotoList photoList = dataProvider.Data as PhotoList;
theWindow.Photos = photoList;
theWindow.Photos.Path = @"..\..\HelloKitty";
theWindow.Show();
}
将theWindow.Show() 方法移到后面,再次运行代码,你会发现Hello Kitty 产品图片列表又可以正常显示了,但还是建议采用ObservableCollection<T>集合类的。
范例程序运行环境:Visual Studio 2008 SP1。如果你对XAML不熟悉,建议你参考如下XAML学习笔记系列: