一、说明
本文代码来源:
《windows phone 7 程序设计》 Charles Petzold
控件效果:
二、要点:
1.ItemControl、子项容器模板(ItemsControl.ItemsPanel)和子项模板(ItemsControl.ItemTemplate)
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:StudentCard />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<petzold:OverlapPanel Orientation="Vertical"
MinimumOverlap="24" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
2.UseControl、VisualStateManager
1).VisualStateManager必须紧跟在于UseControl顶级控件:
<UserControl.RenderTransform>
<TranslateTransform x:Name="translate" />
</UserControl.RenderTransform>
<!-- Border是StudentCard控件的顶级控件-->
<Border.....>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Open">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="translate"
Storyboard.TargetProperty="X"
To="220" Duration="0:0:1" />
</Storyboard>
</VisualState>
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="translate"
Storyboard.TargetProperty="X"
Duration="0:0:1" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Border>
2).当依赖属性
public static readonly DependencyProperty IsOpenProperty =
DependencyProperty.Register("IsOpen",
typeof(bool),
typeof(StudentCard),
new PropertyMetadata(false, OnIsOpenChanged));
改变时就改变控件的视觉状态:
static void OnIsOpenChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
(obj as StudentCard).OnIsOpenChanged(args);
}
void OnIsOpenChanged(DependencyPropertyChangedEventArgs args)
{
VisualStateManager.GoToState(this, IsOpen ? "Open" : "Normal", false);
}
3.重写布局控件Panel中的方法:
1). protected override Size MeasureOverride(Size availableSize);
MeasureOverride方法为该布局控件确定每个子元素的大小。
MeasureOverride调用其所有子元素的Measure方法(UIElement中定义的,密封的Sealed方法)。
各个子元素的Measure方法又调用自己的MeasureOverride,这样一直持续遍历完整棵树。
2).protected override Size ArrangeOverride(Size finalSize);
ArrangeOverride方法为该布局控件把子元素排列到相对于自身的位置。
ArrangeOverride调用其所有子元素的Arrange方法(UIElement中定义的,密封的Sealed方法)。
各个子元素的Arrange方法又调用自己的ArrangeOverride,这样一直持续遍历完整棵树。
三、源码
Mainpage.xmal:
<phone:PhoneApplicationPage x:Class="StudentCardFile.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:elpaso="clr-namespace:ElPasoHighSchool;assembly=ElPasoHighSchool" xmlns:petzold="clr-namespace:Petzold.Phone.Silverlight;assembly=Petzold.Phone.Silverlight" xmlns:local="clr-namespace:StudentCardFile" 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"> <phone:PhoneApplicationPage.Resources> <elpaso:StudentBodyPresenter x:Key="studentBodyPresenter" /> </phone:PhoneApplicationPage.Resources> <!--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="STUDENT CARD FILE" Style="{StaticResource PhoneTextNormalStyle}"/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0" DataContext="{Binding Source={StaticResource studentBodyPresenter}, Path=StudentBody}"> <ScrollViewer> <ItemsControl ItemsSource="{Binding Students}"> <ItemsControl.ItemTemplate> <DataTemplate> <local:StudentCard /> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <petzold:OverlapPanel Orientation="Vertical" MinimumOverlap="24" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </ScrollViewer> </Grid> </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>
StudentCard.xaml
<UserControl x:Class="StudentCardFile.StudentCard" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" Width="240" Height="240"> <UserControl.RenderTransform> <TranslateTransform x:Name="translate" /> </UserControl.RenderTransform> <Border BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="1" Background="{StaticResource PhoneChromeBrush}" CornerRadius="12" Padding="6 0"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Open"> <Storyboard> <DoubleAnimation Storyboard.TargetName="translate" Storyboard.TargetProperty="X" To="220" Duration="0:0:1" /> </Storyboard> </VisualState> <VisualState x:Name="Normal"> <Storyboard> <DoubleAnimation Storyboard.TargetName="translate" Storyboard.TargetProperty="X" Duration="0:0:1" /> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding FullName}" /> <Rectangle Grid.Row="1" Fill="{StaticResource PhoneAccentBrush}" Height="1" Margin="0 0 0 4" /> <Image Grid.Row="2" Source="{Binding PhotoFilename}" /> <StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center"> <TextBlock Text="GPA = " /> <TextBlock Text="{Binding GradePointAverage}" /> </StackPanel> </Grid> </Border> </UserControl>
StudentCard.xaml.cs
using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace StudentCardFile { public partial class StudentCard : UserControl { static List<StudentCard> studentCards = new List<StudentCard>(); static int contactTime; static Point contactPoint; public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(StudentCard), new PropertyMetadata(false, OnIsOpenChanged)); static StudentCard() { Touch.FrameReported += OnTouchFrameReported; } static void OnIsOpenChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { (obj as StudentCard).OnIsOpenChanged(args); } static void OnTouchFrameReported(object sender, TouchFrameEventArgs args) { TouchPoint touchPoint = args.GetPrimaryTouchPoint(null); if (touchPoint != null && touchPoint.Action == TouchAction.Down) { contactPoint = touchPoint.Position; contactTime = args.Timestamp; } else if (touchPoint != null && touchPoint.Action == TouchAction.Up) { // Check if finger is directly over StudentCard or child DependencyObject element = touchPoint.TouchDevice.DirectlyOver; while (element != null && !(element is StudentCard)) element = VisualTreeHelper.GetParent(element); if (element == null) return; // Get lift point and calculate difference Point liftPoint = touchPoint.Position; double distance = Math.Sqrt(Math.Pow(contactPoint.X - liftPoint.X, 2) + Math.Pow(contactPoint.Y - liftPoint.Y, 2)); // Qualify as a Tap if distance < 12 pixels within 1/4 second if (distance < 12 && args.Timestamp - contactTime < 250) { // Enumerate StudentCard objects and set IsOpen property foreach (StudentCard studentCard in studentCards) studentCard.IsOpen = (element == studentCard && !studentCard.IsOpen); } } } public StudentCard() { InitializeComponent(); studentCards.Add(this); } bool IsOpen { set { SetValue(IsOpenProperty, value); } get { return (bool)GetValue(IsOpenProperty); } } void OnIsOpenChanged(DependencyPropertyChangedEventArgs args) { VisualStateManager.GoToState(this, IsOpen ? "Open" : "Normal", false); } } }
用反射工具得到布局控件OverlapPanel的代码:
public class OverlapPanel : Panel { // Fields private Size maxChildSize = new Size(); public static readonly DependencyProperty MinimumOverlapProperty = DependencyProperty.Register("MinimumOverlap", typeof(double), typeof(OverlapPanel), new PropertyMetadata(0.0, new PropertyChangedCallback(null, (IntPtr) OnAffectsMeasure))); public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register("Orientation", typeof(Orientation), typeof(OverlapPanel), new PropertyMetadata((Orientation) 1, new PropertyChangedCallback(null, (IntPtr) OnAffectsMeasure))); // Methods protected override Size ArrangeOverride(Size finalSize) { if (base.get_Children().get_Count() != 0) { double num = 0.0; if (this.Orientation == 1) { num = Math.Max(this.MinimumOverlap, (finalSize.get_Width() - this.maxChildSize.get_Width()) / ((double) (base.get_Children().get_Count() - 1))); } else { num = Math.Max(this.MinimumOverlap, (finalSize.get_Height() - this.maxChildSize.get_Height()) / ((double) (base.get_Children().get_Count() - 1))); } Point point = new Point(); foreach (UIElement element in base.get_Children()) { element.Arrange(new Rect(point, this.maxChildSize)); if (this.Orientation == 1) { point.set_X(point.get_X() + num); } else { point.set_Y(point.get_Y() + num); } } } return finalSize; } protected override Size MeasureOverride(Size availableSize) { if (base.get_Children().get_Count() == 0) { return new Size(0.0, 0.0); } this.maxChildSize = new Size(); foreach (UIElement element in base.get_Children()) { if (this.Orientation == 1) { element.Measure(new Size(double.PositiveInfinity, availableSize.get_Height())); } else { element.Measure(new Size(availableSize.get_Width(), double.PositiveInfinity)); } this.maxChildSize.set_Width(Math.Max(this.maxChildSize.get_Width(), element.get_DesiredSize().get_Width())); this.maxChildSize.set_Height(Math.Max(this.maxChildSize.get_Height(), element.get_DesiredSize().get_Height())); } if (this.Orientation == 1) { double num = this.maxChildSize.get_Width() * base.get_Children().get_Count(); double num2 = this.maxChildSize.get_Width() + (this.MinimumOverlap * (base.get_Children().get_Count() - 1)); if (!double.IsPositiveInfinity(availableSize.get_Width())) { if (num < availableSize.get_Width()) { return new Size(num, this.maxChildSize.get_Height()); } if (num2 < availableSize.get_Width()) { return new Size(availableSize.get_Width(), this.maxChildSize.get_Height()); } } return new Size(num2, this.maxChildSize.get_Height()); } double num3 = this.maxChildSize.get_Height() * base.get_Children().get_Count(); double num4 = this.maxChildSize.get_Height() + (this.MinimumOverlap * (base.get_Children().get_Count() - 1)); if (double.IsPositiveInfinity(availableSize.get_Height())) { return new Size(this.maxChildSize.get_Width(), num4); } if (num3 < availableSize.get_Height()) { return new Size(this.maxChildSize.get_Width(), num3); } if (num4 < availableSize.get_Height()) { return new Size(this.maxChildSize.get_Width(), availableSize.get_Height()); } return new Size(this.maxChildSize.get_Width(), num4); } private static void OnAffectsMeasure(DependencyObject obj, DependencyPropertyChangedEventArgs args) { (obj as OverlapPanel).InvalidateMeasure(); } // Properties public double MinimumOverlap { get { return (double) base.GetValue(MinimumOverlapProperty); } set { base.SetValue(MinimumOverlapProperty, value); } } public Orientation Orientation { get { return (Orientation) base.GetValue(OrientationProperty); } set { base.SetValue(OrientationProperty, value); } } } Collapse Methods
四、MainPage.xmal中的数据源:
。。。
xmlns:elpaso="clr-namespace:ElPasoHighSchool;assembly=ElPasoHighSchool"
。。。
<phone:PhoneApplicationPage.Resources>
<elpaso:StudentBodyPresenter x:Key="studentBodyPresenter" />
</phone:PhoneApplicationPage.Resources>
ElPasoHighSchool.dll 反射工具得到如下用到得类:
Student.c
public class Student : INotifyPropertyChanged { // Fields private string firstName; private string fullName; private decimal gradePointAverage; private string lastName; private string middleName; private string photoFilename; private PropertyChangedEventHandler PropertyChanged; private string sex; // Events public event PropertyChangedEventHandler PropertyChanged { add { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Combine(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } remove { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Remove(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } } // Methods protected virtual void OnPropertyChanged(string propChanged) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propChanged)); } } // Properties public string FirstName { get { return this.firstName; } set { if (this.firstName != value) { this.firstName = value; this.OnPropertyChanged("FirstName"); } } } public string FullName { get { return this.fullName; } set { if (this.fullName != value) { this.fullName = value; this.OnPropertyChanged("FullName"); } } } public decimal GradePointAverage { get { return this.gradePointAverage; } set { if (this.gradePointAverage != value) { this.gradePointAverage = value; this.OnPropertyChanged("GradePointAverage"); } } } public string LastName { get { return this.lastName; } set { if (this.lastName != value) { this.lastName = value; this.OnPropertyChanged("LastName"); } } } public string MiddleName { get { return this.middleName; } set { if (this.middleName != value) { this.middleName = value; this.OnPropertyChanged("MiddleName"); } } } public string PhotoFilename { get { return this.photoFilename; } set { if (this.photoFilename != value) { this.photoFilename = value; this.OnPropertyChanged("PhotoFilename"); } } } public string Sex { get { return this.sex; } set { if (this.sex != value) { this.sex = value; this.OnPropertyChanged("Sex"); } } } } Collapse Methods
StudentBody.cs
public class StudentBody : INotifyPropertyChanged { // Fields private PropertyChangedEventHandler PropertyChanged; private string school; private ObservableCollection<Student> students = new ObservableCollection<Student>(); // Events public event PropertyChangedEventHandler PropertyChanged { add { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Combine(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } remove { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Remove(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } } // Methods protected virtual void OnPropertyChanged(string propChanged) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propChanged)); } } // Properties public string School { get { return this.school; } set { if (this.school != value) { this.school = value; this.OnPropertyChanged("School"); } } } public ObservableCollection<Student> Students { get { return this.students; } set { if (this.students != value) { this.students = value; this.OnPropertyChanged("Students"); } } } } Collapse Methods
public class StudentBodyPresenter : INotifyPropertyChanged { // Fields private PropertyChangedEventHandler PropertyChanged; private Random rand = new Random(); private StudentBody studentBody; // Events public event PropertyChangedEventHandler PropertyChanged { add { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Combine(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } remove { PropertyChangedEventHandler handler2; PropertyChangedEventHandler propertyChanged = this.PropertyChanged; do { handler2 = propertyChanged; PropertyChangedEventHandler handler3 = (PropertyChangedEventHandler) Delegate.Remove(handler2, value); propertyChanged = Interlocked.CompareExchange<PropertyChangedEventHandler>(ref this.PropertyChanged, handler3, handler2); } while (propertyChanged != handler2); } } // Methods public StudentBodyPresenter() { Uri uri = new Uri("http://www.charlespetzold.com/Students/students.xml"); WebClient client = new WebClient(); client.add_DownloadStringCompleted(new DownloadStringCompletedEventHandler(this, (IntPtr) this.OnDownloadStringCompleted)); client.DownloadStringAsync(uri); } private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs args) { StringReader reader = new StringReader(args.get_Result()); XmlSerializer serializer = new XmlSerializer(typeof(StudentBody)); this.StudentBody = serializer.Deserialize(reader) as StudentBody; DispatcherTimer timer = new DispatcherTimer(); timer.add_Tick(new EventHandler(this.TimerOnTick)); timer.set_Interval(TimeSpan.FromMilliseconds(100.0)); timer.Start(); } protected virtual void OnPropertyChanged(string propChanged) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propChanged)); } } private void TimerOnTick(object sender, EventArgs args) { int num = this.rand.Next(this.studentBody.Students.Count); Student student = this.studentBody.Students[num]; double num2 = 1.0 + ((this.rand.NextDouble() - 0.5) / 5.0); student.GradePointAverage = Math.Max(0M, Math.Min(5M, decimal.Round(((decimal) num2) * student.GradePointAverage, 2))); } // Properties public StudentBody StudentBody { get { return this.studentBody; } protected set { if (this.studentBody != value) { this.studentBody = value; this.OnPropertyChanged("StudentBody"); } } } } Collapse Methods
要点:
1).数据是存在一个名为students.xml,地址为:
http://www.charlespetzold.com/Students/students.xml
students.xml:
<?xml version="1.0" encoding="utf-8" ?> - <StudentBody xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <School>El Paso High School</School> - <Students> - <Student> <FullName>Adkins Bowden</FullName> <FirstName>Adkins</FirstName> <MiddleName /> <LastName>Bowden</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AdkinsBowden.png</PhotoFilename> <GradePointAverage>2.71</GradePointAverage> </Student> - <Student> <FullName>Alfred Black</FullName> <FirstName>Alfred</FirstName> <MiddleName /> <LastName>Black</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AlfredBlack.png</PhotoFilename> <GradePointAverage>2.87</GradePointAverage> </Student> - <Student> <FullName>Alice Bishop</FullName> <FirstName>Alice</FirstName> <MiddleName /> <LastName>Bishop</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AliceBishop.png</PhotoFilename> <GradePointAverage>3.68</GradePointAverage> </Student> - <Student> <FullName>Alma Hermine Morrison</FullName> <FirstName>Alma</FirstName> <MiddleName>Hermine</MiddleName> <LastName>Morrison</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AlmaHermineMorrison.png</PhotoFilename> <GradePointAverage>1.99</GradePointAverage> </Student> - <Student> <FullName>Angie Foster</FullName> <FirstName>Angie</FirstName> <MiddleName /> <LastName>Foster</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AngieFoster.png</PhotoFilename> <GradePointAverage>1.37</GradePointAverage> </Student> - <Student> <FullName>Antoinette Matkin</FullName> <FirstName>Antoinette</FirstName> <MiddleName /> <LastName>Matkin</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/AntoinetteMatkin.png</PhotoFilename> <GradePointAverage>1.17</GradePointAverage> </Student> - <Student> <FullName>Barbara Byers</FullName> <FirstName>Barbara</FirstName> <MiddleName /> <LastName>Byers</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/BarbaraByers.png</PhotoFilename> <GradePointAverage>1.85</GradePointAverage> </Student> - <Student> <FullName>Bernadine Wilma Schultz</FullName> <FirstName>Bernadine</FirstName> <MiddleName>Wilma</MiddleName> <LastName>Schultz</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/BernadineWilmaSchultz.png</PhotoFilename> <GradePointAverage>3.65</GradePointAverage> </Student> - <Student> <FullName>Bernita Thomas</FullName> <FirstName>Bernita</FirstName> <MiddleName /> <LastName>Thomas</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/BernitaThomas.png</PhotoFilename> <GradePointAverage>1.96</GradePointAverage> </Student> - <Student> <FullName>Camille Kibler</FullName> <FirstName>Camille</FirstName> <MiddleName /> <LastName>Kibler</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/CamilleKibler.png</PhotoFilename> <GradePointAverage>2.54</GradePointAverage> </Student> - <Student> <FullName>Charles Carter</FullName> <FirstName>Charles</FirstName> <MiddleName /> <LastName>Carter</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/CharlesCarter.png</PhotoFilename> <GradePointAverage>1.12</GradePointAverage> </Student> - <Student> <FullName>Charles Edgar Virden</FullName> <FirstName>Charles</FirstName> <MiddleName>Edgar</MiddleName> <LastName>Virden</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/CharlesEdgarVirden.png</PhotoFilename> <GradePointAverage>2.28</GradePointAverage> </Student> - <Student> <FullName>Charles Kilburn</FullName> <FirstName>Charles</FirstName> <MiddleName /> <LastName>Kilburn</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/CharlesKilburn.png</PhotoFilename> <GradePointAverage>1.72</GradePointAverage> </Student> - <Student> <FullName>Christian Jungjohann</FullName> <FirstName>Christian</FirstName> <MiddleName /> <LastName>Jungjohann</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ChristianJungjohann.png</PhotoFilename> <GradePointAverage>3.73</GradePointAverage> </Student> - <Student> <FullName>Christina Moelich</FullName> <FirstName>Christina</FirstName> <MiddleName /> <LastName>Moelich</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ChristinaMoelich.png</PhotoFilename> <GradePointAverage>2.41</GradePointAverage> </Student> - <Student> <FullName>Clara Louise Fink</FullName> <FirstName>Clara</FirstName> <MiddleName>Louise</MiddleName> <LastName>Fink</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ClaraLouiseFink.png</PhotoFilename> <GradePointAverage>3.21</GradePointAverage> </Student> - <Student> <FullName>Clarinda Corbin</FullName> <FirstName>Clarinda</FirstName> <MiddleName /> <LastName>Corbin</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ClarindaCorbin.png</PhotoFilename> <GradePointAverage>2.73</GradePointAverage> </Student> - <Student> <FullName>Dayverne Stearns</FullName> <FirstName>Dayverne</FirstName> <MiddleName /> <LastName>Stearns</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/DayverneStearns.png</PhotoFilename> <GradePointAverage>1.28</GradePointAverage> </Student> - <Student> <FullName>Dorothy Congdon</FullName> <FirstName>Dorothy</FirstName> <MiddleName /> <LastName>Congdon</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/DorothyCongdon.png</PhotoFilename> <GradePointAverage>2.07</GradePointAverage> </Student> - <Student> <FullName>Earl Weisiger</FullName> <FirstName>Earl</FirstName> <MiddleName /> <LastName>Weisiger</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EarlWeisiger.png</PhotoFilename> <GradePointAverage>1.28</GradePointAverage> </Student> - <Student> <FullName>Edna Richardson</FullName> <FirstName>Edna</FirstName> <MiddleName /> <LastName>Richardson</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EdnaRichardson.png</PhotoFilename> <GradePointAverage>2.39</GradePointAverage> </Student> - <Student> <FullName>Eldon Routledge</FullName> <FirstName>Eldon</FirstName> <MiddleName /> <LastName>Routledge</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EldonRoutledge.png</PhotoFilename> <GradePointAverage>3.26</GradePointAverage> </Student> - <Student> <FullName>Elgie Means</FullName> <FirstName>Elgie</FirstName> <MiddleName /> <LastName>Means</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ElgieMeans.png</PhotoFilename> <GradePointAverage>1.16</GradePointAverage> </Student> - <Student> <FullName>Elizabeth Barnes</FullName> <FirstName>Elizabeth</FirstName> <MiddleName /> <LastName>Barnes</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ElizabethBarnes.png</PhotoFilename> <GradePointAverage>3.68</GradePointAverage> </Student> - <Student> <FullName>Elizabeth Bruce Lucas</FullName> <FirstName>Elizabeth</FirstName> <MiddleName>Bruce</MiddleName> <LastName>Lucas</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ElizabethBruceLucas.png</PhotoFilename> <GradePointAverage>3.43</GradePointAverage> </Student> - <Student> <FullName>Elizabeth Routledge</FullName> <FirstName>Elizabeth</FirstName> <MiddleName /> <LastName>Routledge</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ElizabethRoutledge.png</PhotoFilename> <GradePointAverage>3.86</GradePointAverage> </Student> - <Student> <FullName>Eugene Smith</FullName> <FirstName>Eugene</FirstName> <MiddleName /> <LastName>Smith</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EugeneSmith.png</PhotoFilename> <GradePointAverage>3.92</GradePointAverage> </Student> - <Student> <FullName>Eunice Anderson</FullName> <FirstName>Eunice</FirstName> <MiddleName /> <LastName>Anderson</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EuniceAnderson.png</PhotoFilename> <GradePointAverage>3.96</GradePointAverage> </Student> - <Student> <FullName>Eunice Winifred Preston</FullName> <FirstName>Eunice</FirstName> <MiddleName>Winifred</MiddleName> <LastName>Preston</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/EuniceWinifredPreston.png</PhotoFilename> <GradePointAverage>2.70</GradePointAverage> </Student> - <Student> <FullName>George Johnston</FullName> <FirstName>George</FirstName> <MiddleName /> <LastName>Johnston</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/GeorgeJohnston.png</PhotoFilename> <GradePointAverage>1.07</GradePointAverage> </Student> - <Student> <FullName>Grace Fleck</FullName> <FirstName>Grace</FirstName> <MiddleName /> <LastName>Fleck</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/GraceFleck.png</PhotoFilename> <GradePointAverage>1.96</GradePointAverage> </Student> - <Student> <FullName>Harry Stearns</FullName> <FirstName>Harry</FirstName> <MiddleName /> <LastName>Stearns</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/HarryStearns.png</PhotoFilename> <GradePointAverage>3.61</GradePointAverage> </Student> - <Student> <FullName>Henry Avery Schumacher</FullName> <FirstName>Henry</FirstName> <MiddleName>Avery</MiddleName> <LastName>Schumacher</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/HenryAverySchumacher.png</PhotoFilename> <GradePointAverage>1.31</GradePointAverage> </Student> - <Student> <FullName>Idus Gilbert</FullName> <FirstName>Idus</FirstName> <MiddleName /> <LastName>Gilbert</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/IdusGilbert.png</PhotoFilename> <GradePointAverage>1.23</GradePointAverage> </Student> - <Student> <FullName>Irene Bryan</FullName> <FirstName>Irene</FirstName> <MiddleName /> <LastName>Bryan</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/IreneBryan.png</PhotoFilename> <GradePointAverage>2.52</GradePointAverage> </Student> - <Student> <FullName>Isabelle Valentine</FullName> <FirstName>Isabelle</FirstName> <MiddleName /> <LastName>Valentine</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/IsabelleValentine.png</PhotoFilename> <GradePointAverage>2.80</GradePointAverage> </Student> - <Student> <FullName>Joseph Idus Lambert</FullName> <FirstName>Joseph</FirstName> <MiddleName>Idus</MiddleName> <LastName>Lambert</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/JosephIdusLambert.png</PhotoFilename> <GradePointAverage>2.13</GradePointAverage> </Student> - <Student> <FullName>Kate Mulcahy</FullName> <FirstName>Kate</FirstName> <MiddleName /> <LastName>Mulcahy</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/KateMulcahy.png</PhotoFilename> <GradePointAverage>2.80</GradePointAverage> </Student> - <Student> <FullName>Katherine Glenn</FullName> <FirstName>Katherine</FirstName> <MiddleName /> <LastName>Glenn</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/KatherineGlenn.png</PhotoFilename> <GradePointAverage>1.88</GradePointAverage> </Student> - <Student> <FullName>Kathleen Elizabeth Faris</FullName> <FirstName>Kathleen</FirstName> <MiddleName>Elizabeth</MiddleName> <LastName>Faris</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/KathleenElizabethFaris.png</PhotoFilename> <GradePointAverage>2.69</GradePointAverage> </Student> - <Student> <FullName>Lena Butchofsky</FullName> <FirstName>Lena</FirstName> <MiddleName /> <LastName>Butchofsky</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/LenaButchofsky.png</PhotoFilename> <GradePointAverage>2.72</GradePointAverage> </Student> - <Student> <FullName>Lillian Lockwood</FullName> <FirstName>Lillian</FirstName> <MiddleName /> <LastName>Lockwood</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/LillianLockwood.png</PhotoFilename> <GradePointAverage>1.07</GradePointAverage> </Student> - <Student> <FullName>Louise Isabelle Springer</FullName> <FirstName>Louise</FirstName> <MiddleName>Isabelle</MiddleName> <LastName>Springer</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/LouiseIsabelleSpringer.png</PhotoFilename> <GradePointAverage>1.66</GradePointAverage> </Student> - <Student> <FullName>Lucas Bacon</FullName> <FirstName>Lucas</FirstName> <MiddleName /> <LastName>Bacon</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/LucasBacon.png</PhotoFilename> <GradePointAverage>1.17</GradePointAverage> </Student> - <Student> <FullName>Margaret Bryan</FullName> <FirstName>Margaret</FirstName> <MiddleName /> <LastName>Bryan</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MargaretBryan.png</PhotoFilename> <GradePointAverage>3.21</GradePointAverage> </Student> - <Student> <FullName>Maria Mateus</FullName> <FirstName>Maria</FirstName> <MiddleName /> <LastName>Mateus</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MariaMateus.png</PhotoFilename> <GradePointAverage>3.92</GradePointAverage> </Student> - <Student> <FullName>Marie Schwartz</FullName> <FirstName>Marie</FirstName> <MiddleName /> <LastName>Schwartz</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MarieSchwartz.png</PhotoFilename> <GradePointAverage>3.53</GradePointAverage> </Student> - <Student> <FullName>Mary Frances Henderson</FullName> <FirstName>Mary</FirstName> <MiddleName>Frances</MiddleName> <LastName>Henderson</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MaryFrancesHenderson.png</PhotoFilename> <GradePointAverage>3.91</GradePointAverage> </Student> - <Student> <FullName>Mary Keating</FullName> <FirstName>Mary</FirstName> <MiddleName /> <LastName>Keating</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MaryKeating.png</PhotoFilename> <GradePointAverage>3.53</GradePointAverage> </Student> - <Student> <FullName>Mary Redmond</FullName> <FirstName>Mary</FirstName> <MiddleName /> <LastName>Redmond</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MaryRedmond.png</PhotoFilename> <GradePointAverage>3.51</GradePointAverage> </Student> - <Student> <FullName>Mattie Clark</FullName> <FirstName>Mattie</FirstName> <MiddleName /> <LastName>Clark</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MattieClark.png</PhotoFilename> <GradePointAverage>1.98</GradePointAverage> </Student> - <Student> <FullName>Mildred Helen Marston</FullName> <FirstName>Mildred</FirstName> <MiddleName>Helen</MiddleName> <LastName>Marston</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MildredHelenMarston.png</PhotoFilename> <GradePointAverage>2.70</GradePointAverage> </Student> - <Student> <FullName>Mineta Henning</FullName> <FirstName>Mineta</FirstName> <MiddleName /> <LastName>Henning</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MinetaHenning.png</PhotoFilename> <GradePointAverage>2.71</GradePointAverage> </Student> - <Student> <FullName>Minnie Lee Lassiter</FullName> <FirstName>Minnie</FirstName> <MiddleName>Lee</MiddleName> <LastName>Lassiter</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MinnieLeeLassiter.png</PhotoFilename> <GradePointAverage>1.26</GradePointAverage> </Student> - <Student> <FullName>Moline Lopas Hughes</FullName> <FirstName>Moline</FirstName> <MiddleName>Lopas</MiddleName> <LastName>Hughes</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/MolineLopasHughes.png</PhotoFilename> <GradePointAverage>1.79</GradePointAverage> </Student> - <Student> <FullName>Nannie Hammons</FullName> <FirstName>Nannie</FirstName> <MiddleName /> <LastName>Hammons</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/NannieHammons.png</PhotoFilename> <GradePointAverage>1.70</GradePointAverage> </Student> - <Student> <FullName>Nell Mulcahy</FullName> <FirstName>Nell</FirstName> <MiddleName /> <LastName>Mulcahy</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/NellMulcahy.png</PhotoFilename> <GradePointAverage>2.33</GradePointAverage> </Student> - <Student> <FullName>Nelson Rheinheimer</FullName> <FirstName>Nelson</FirstName> <MiddleName /> <LastName>Rheinheimer</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/NelsonRheinheimer.png</PhotoFilename> <GradePointAverage>3.56</GradePointAverage> </Student> - <Student> <FullName>Opal Edson Hadlock</FullName> <FirstName>Opal</FirstName> <MiddleName>Edson</MiddleName> <LastName>Hadlock</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/OpalEdsonHadlock.png</PhotoFilename> <GradePointAverage>2.42</GradePointAverage> </Student> - <Student> <FullName>Ralph O'Neill</FullName> <FirstName>Ralph</FirstName> <MiddleName /> <LastName>O'Neill</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/RalphO'Neill.png</PhotoFilename> <GradePointAverage>3.18</GradePointAverage> </Student> - <Student> <FullName>Ramiel Jungjohann</FullName> <FirstName>Ramiel</FirstName> <MiddleName /> <LastName>Jungjohann</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/RamielJungjohann.png</PhotoFilename> <GradePointAverage>3.90</GradePointAverage> </Student> - <Student> <FullName>Reed Harlan</FullName> <FirstName>Reed</FirstName> <MiddleName /> <LastName>Harlan</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ReedHarlan.png</PhotoFilename> <GradePointAverage>3.46</GradePointAverage> </Student> - <Student> <FullName>Rose Clayton</FullName> <FirstName>Rose</FirstName> <MiddleName /> <LastName>Clayton</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/RoseClayton.png</PhotoFilename> <GradePointAverage>2.11</GradePointAverage> </Student> - <Student> <FullName>Ross Hill</FullName> <FirstName>Ross</FirstName> <MiddleName /> <LastName>Hill</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/RossHill.png</PhotoFilename> <GradePointAverage>2.83</GradePointAverage> </Student> - <Student> <FullName>Ruy Darnall</FullName> <FirstName>Ruy</FirstName> <MiddleName /> <LastName>Darnall</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/RuyDarnall.png</PhotoFilename> <GradePointAverage>1.75</GradePointAverage> </Student> - <Student> <FullName>Steve Lattner</FullName> <FirstName>Steve</FirstName> <MiddleName /> <LastName>Lattner</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/SteveLattner.png</PhotoFilename> <GradePointAverage>2.44</GradePointAverage> </Student> - <Student> <FullName>Therese Youngberg</FullName> <FirstName>Therese</FirstName> <MiddleName /> <LastName>Youngberg</LastName> <Sex>Female</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/ThereseYoungberg.png</PhotoFilename> <GradePointAverage>2.95</GradePointAverage> </Student> - <Student> <FullName>Walter Ponsford</FullName> <FirstName>Walter</FirstName> <MiddleName /> <LastName>Ponsford</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/WalterPonsford.png</PhotoFilename> <GradePointAverage>2.52</GradePointAverage> </Student> - <Student> <FullName>William Sheley Warnock</FullName> <FirstName>William</FirstName> <MiddleName>Sheley</MiddleName> <LastName>Warnock</LastName> <Sex>Male</Sex> <PhotoFilename>http://www.charlespetzold.com/Students/WilliamSheleyWarnock.png</PhotoFilename> <GradePointAverage>1.82</GradePointAverage> </Student> </Students> </StudentBody>
用到如下方法获得xml文件:
public StudentBodyPresenter() { Uri uri = new Uri("http://www.charlespetzold.com/Students/students.xml"); WebClient client = new WebClient(); client.add_DownloadStringCompleted(new DownloadStringCompletedEventHandler(this, (IntPtr) this.OnDownloadStringCompleted)); client.DownloadStringAsync(uri); }
2).然后用反序列化得到StudentBody对象:
private void OnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs args) { StringReader reader = new StringReader(args.get_Result()); XmlSerializer serializer = new XmlSerializer(typeof(StudentBody)); this.StudentBody = serializer.Deserialize(reader) as StudentBody; DispatcherTimer timer = new DispatcherTimer(); timer.add_Tick(new EventHandler(this.TimerOnTick)); timer.set_Interval(TimeSpan.FromMilliseconds(100.0)); timer.Start(); } private void TimerOnTick(object sender, EventArgs args) { int num = this.rand.Next(this.studentBody.Students.Count); Student student = this.studentBody.Students[num]; double num2 = 1.0 + ((this.rand.NextDouble() - 0.5) / 5.0); student.GradePointAverage = Math.Max(0M, Math.Min(5M, decimal.Round(((decimal) num2) * student.GradePointAverage, 2))); }
StudentBody用private ObservableCollection<Student> students;保存所有的Student对象,反序列化时,students得到赋值。