2012-03-02 12 views
1

OData Webサービスから取得されたアイテムのリストをリストボックスにロードしようとしています。データの取り込みがうまくいき、アイテムのリストを取得しています。リストボックスは実際に動作し、アイテムを表示しますが、アプリケーションを起動するたびに表示されるわけではありません。非同期にデータを取得する必要があるため、データが返される前にリストボックスがロードされることがあります。それが実行されると、データがまだ読み込まれていることを示すために、1つの「空の」項目を含むリストをフィードします。秒後にデータがロードされ、リストのPropertyChangedイベントが発生します。リストのプロパティの中の私のブレークポイントがトリガされ、リストに正しい項目が含まれていることを確認します。しかし、リストボックスには新しいアイテムは表示されず、古い「空の」アイテムだけが表示されます。 xamlが明らかにリストを要求していますが、新しい項目のレイアウトをリフレッシュしないことは、私にとって非常に奇妙なようです。Silverlightリストボックスでリストが更新されない

最初にViewModelを初期化するコード。 ModelReferenceMapはINotifyPropertyChangedを実装しているため、OnPropertyChanged( "Areas"); (これはプロパティからのリストのフェッチをトリガーしますが、ビューを更新しません)。

public ModelReferenceMap(Uri serviceURI) 
    { 
     // Try initialising these lists to a non null but empty list 
     // in the hope it will stop the lists breaking when the service 
     // is a little bit slow... 
     areas = new List<ModelReferenceItem> { new ModelReferenceItem(null) }; 
     // This is a ServiceReference entity context which will retrieve the data from the OData service 
     context = new LiveEntities(serviceURI); 
     // SendingRequest adds credentials for the web service 
     context.SendingRequest += context_SendingRequest; 
     // The query to retrieve the items 
     var areaQuery = from i in context.MigrationItems where i.FusionPTID == 0 && i.Type == "AreaType" orderby i.Name select i; 
     // On completion this asynccallback is called 
     AsyncCallback ac = iasyncResult => 
     { 
      // Populates the List with the data items 
      areas = (from i in ((DataServiceQuery<MigrationItem>) areaQuery).EndExecute(iasyncResult) 
        select new ModelReferenceItem(i)).ToList(); 
      foreach (ModelReferenceItem area in areas) 
      { 
       if (selectedArea == null) 
        selectedArea = area; 
       area.PropertyChanged += referenceItem_PropertyChanged; 
      } 
      // The Xaml Listbox has its ItemsSource bound to the Areas property. This should trigger a refresh of the listbox contents shouldn't it? 
      OnPropertyChanged("Areas"); 
      OnPropertyChanged("SelectedArea"); 
     }; 
     // Start the query 
     ((DataServiceQuery<MigrationItem>)areaQuery).BeginExecute(ac, null); 
    } 

今やXAML。リストボックスのDataContextは、ReferenceMap(ModelReferenceMapのシングルトンインスタンスを公開するメインのViewModelのプロパティ)です。私はItemsSourceをエリアにバインドしました。

 <ListBox Grid.Row="0" DataContext="{Binding ReferenceMap}" ItemsSource="{Binding Areas}" SelectedItem="{Binding SelectedArea, Mode=TwoWay}" HorizontalAlignment="Stretch" Margin="3" Name="listBoxFusionAreas" VerticalAlignment="Stretch"> 
      <ListBox.ItemContainerStyle> 
       <Style TargetType="ListBoxItem"> 
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
       </Style> 
      </ListBox.ItemContainerStyle> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Grid Background="{Binding CompleteStatusColour}"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="*"/> 
          <ColumnDefinition Width="Auto"/> 
         </Grid.ColumnDefinitions> 
         <TextBlock FontSize="12" Text="{Binding Name}" /> 
         <TextBlock Grid.Column="1" FontSize="12" Text="{Binding Count}"/> 
        </Grid> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

領域プロパティは、バインディングが機能していることを正しくトリガーしています。サービスデータが検索された後(つまり1回だけ)、エリアが要求されると、リストは完全に機能します。ただし、サービスデータが返される前にAreasプロパティがトリガされた場合(つまり、単一の '空'アイテムの場合)、OnPropertyChanged( "Areas")中に再びトリガされます。今度は、リストには元の「空の」項目だけが表示されます。

私は間違っていますか?

答えて

3

ViewModelのコレクションにバインドするときは、コレクション内のアイテムが変更されるかどうかを確認する必要がありますか?あなたのケースでは、私がいることをあげる

ObservableCollection<ModelReferenceItem> areas ; 

代わりの

List<ModelReferenceItem> area; 

のObservableCollectionは(追加/削除)コレクションの変更についてのご見解を通知INoifyCollectionChangedイベントを実装

+0

を実装する必要がありますしかし、サービスが最終的にデータを返すときにリスト全体が置き換えられます。個々のアイテムを追加したり削除したりすることはあまりありません。それがすぐに動作しない場合は、既存のリストを置き換えるのではなく、明確で追加して試してみます... –

+0

このトリックを完了したと思われます。エリアはObservableCollection になりました。データが返ってきたら、私はareas.Clear()を呼び出します。次に、areas.Add();処理されている個々のアイテム、つまりイベントハンドラを追加します。クイックレスポンスへの歓声。 –

+0

p.s.確かに私は数年前にこの問題に遭遇しました...しかし、私はあなたが18ヶ月間iOS上で開発していくとどうなるのでしょうか?( –

関連する問題