WP8 中的全景控件有一个已知的数据绑定错误。该错误的症状是 SelectionChanged 不会触发,SelectedIndex 和 SelectedItem 不可靠,并且返回导航到带有全景的页面会重置全景所选项目。
例如,以下代码示例永远不会触发 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>
to更改为ObservableCollection<object>
并在类中添加一些代码Cow
:
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new ObservableCollection<object>()
{
new Cow("Foo"),
new Cow("Bar"),
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 值触发: