9

私はWindows Phone 7用のアプリケーションを作成しましたが、最近Windows Phone 8にアップグレードしました。残念ながら、私はアップグレードの直後に問題に遭遇しました。このアプリの主な部分は、データバインドされたPanoramaコントロールです。 SelectionChangedで私は新しいPanoramaItem + 1のデータを取得しています(データをあらかじめ選択しておくと、最終的にアイテムに移動するときにそこに保存されます)。 WP7ではうまくいきましたが、SelectionChangedイベントはWP8で起動しません。Windows Phone 8 Panorama SelectionChanged&Databinding

アップグレードされていない新しいWP8アプリで問題を再現しました。また、データバインドされたコントロールにも分離されています。パノラマアイテムを静的に追加すると、SelectionChangedイベントが正常に発生します。

WP8で何かが見つからないのですか?推奨される回避策はありますか?

静的サンプルとデータバインドされたサンプルを使用してGitHubリポジトリを作成し、動作するものと動作しないものを示します。 https://github.com/bthubbard/DatabindingIssues

答えて

18

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; } 
} 

1つの明らかな修正は、手動でコードビハインドでPanoramaItemsを初期化することになります。

もう1つの解決策は、コレクションを型付きから型なしに変更し、次のコードスニペットをバインドされたデータクラスに追加することです。それでは、ObservableCollection<object>ObservableCollection<Cow>から我々のコードを変更し、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(); 
    } 
} 

、我々は正しいSelectedIndexを値で期待通り、我々は火をSelectionChanged見ることができ、このコードスニペットを実行するときPanorama firing the SelecitonChanged event with the correct SelectedIndex Panorama firing the SelecitonChanged event with the correct SelectedIndex

+3

感謝。あなたは小規模なアプリでうまく動作しますが、より関わりのあるもので少し痛みが伴うかもしれません。これはいつ修正されるのでしょうか? – Brandon

+0

私はちょうどテストし、今SelectionChangedイベントはWP8で動作するようです。 – Sopuli

2

ポータブルクラスライブラリ内のViewModelを持っている人のためだけのマイナーヒント - 私は私のviewmodelsの基本クラスでこのコードを配置:

if (Equals(obj.GetType().Name, "PanoramaItem")) 
{ 
    var datacontextProperty = obj.GetType().GetRuntimeProperty("DataContext"); 
    var datacontext = datacontextProperty.GetValue(obj); 
    return Equals(datacontext, this); 
} 

これは私の問題を解決しました。 @ソプリのコメントは、テストしたWP8デバイスではまだこの問題があります。 (ノキアLumia 920、WP8.0.10517.150)


VB.NET版:あなたの応答のための

Public Overrides Function Equals(obj As Object) As Boolean 
    If Equals(obj.GetType.Name, "PanoramaItem") Then 
     Dim datacontextProperty = System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperty(obj.GetType, "DataContext") 
     Dim datacontext = datacontextProperty.GetValue(obj) 
     Return Equals(datacontext, Me) 
    Else 
     Return MyBase.Equals(obj) 
    End If 
End Function 
+0

申し訳ありませんが、正確にあなたのPCL VMにこれを入れましたか? 'InotifyChanged'を実装している何らかの種類の' BindableBase'クラスのコンストラクタで? –

+0

私のビューモードはPCLにあります。それらはすべてViewModelBaseクラス(PCLのalsinクラス)から継承されています。 上記のコードはEquals演算子の一部です: – espenalb

+0

パーフェクト。私はVB.NETバージョンのC#コードを少し追加しました。 –

関連する問題