我为
Windows Phone 7编写了一个应用程序,最近我将其升级到Windows Phone 8,并计划添加一些功能.不幸的是,升级后我立即遇到问题.应用程序的主要部分是数据绑定的Panorama控件.在SelectionChanged我正在获取新的PanoramaItem 1的数据(预选数据,所以当人最终到达该项目时).这在WP7中工作正常,但是SelectionChanged事件不会用WP8触发.
我已经通过一个未升级的新WP8应用程序再现了这个问题,它也被隔离到数据绑定控件.如果我静态添加PanoramaItems,SelectionChanged事件将被触发.
我错过了什么,还是这只是一个直截了当的WP8中的bug?任何推荐的解决方法?
我有一个GitHub repo与一个静态样本和一个数据绑定的样本,以显示什么工作和什么不起作用. https://github.com/bthubbard/DatabindingIssues
解决方法
WP8中的Panorama控件有一个已知的数据绑定错误. Bug的症状是SelectionChanged不启动,SelectedIndex& SelectedItem不可靠,并且将Panorama导航到具有“全景”选项的全景照片.
例如,以下代码示例将永远不会触发MessageBox和SelectedIndex& SelectedItem不会指示正确的预期值.
<phone:Panorama x:Name="panorama" ItemsSource="{Binding}" SelectionChanged="Panorama_SelectionChanged_1"> <phone:Panorama.HeaderTemplate> <DataTemplate> <ContentControl Content="{Binding Name}" /> </DataTemplate> </phone:Panorama.HeaderTemplate> <phone:Panorama.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding Name}" /> </DataTemplate> </phone:Panorama.ItemTemplate> </phone:Panorama>
private void MainPage_Loaded(object sender,RoutedEventArgs e) { this.DataContext = new ObservableCollection<Cow>() { new Cow("Foo"),new Cow("Bar"),new Cow("Baz") }; } private void Panorama_SelectionChanged_1(object sender,SelectionChangedEventArgs e) { MessageBox.Show("Panorama_SelectionChanged_1: " + panorama.SelectedIndex); } public class Cow { public Cow(string name) { Name = name; } public string Name { get; set; } }
一个明显的修复将是在代码隐藏中手动初始化PanoramaItems.
另一个解决方案是将我们的集合从类型更改为无类型,并将以下代码片段添加到有限数据类中.所以我们来从ObservableCollection< Cow>到ObservableCollection< object>并在Cow类中添加一些代码:
private void MainPage_Loaded(object sender,RoutedEventArgs e) { this.DataContext = new ObservableCollection<object>() { new Cow("Foo"),new Cow("Baz") }; } public class Cow { public Cow(string name) { Name = name; } public string Name { get; set; } public override bool Equals(object obj) { if ((obj != null) && (obj.GetType() == typeof(PanoramaItem))) { var thePanoItem = (PanoramaItem)obj; return base.Equals(thePanoItem.Header); } else { return base.Equals(obj); } } public override int GetHashCode() { return base.GetHashCode(); } }
现在,当我们运行这个代码片段时,我们可以看到SelectionChanged触发,如预期的那样,使用正确的SelectedIndex值: