silverlight – Windows Phone 8 Panorama SelectionChanged&Databinding

我为 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值:

相关文章

如何在Silverlight4(XAML)中绑定IsEnabled属性?我试过简单的...
我正在编写我的第一个vb.net应用程序(但我也会在这里标记c#,...
ProcessFile()是在UIThread上运行还是在单独的线程上运行.如...
我从同行那里听说,对sharepoint的了解对职业生涯有益.我们不...
我正在尝试保存一个类我的类对象的集合.我收到一个错误说明:...
我需要根据Silverlight中的某些配置值设置给定控件的Style.我...