2009-04-30 19 views
8

そのバインドをリフレッシュするItemsSourceを取得する方法

GetAll()は、ViewModelのObservableCollectionプロパティです。

public static ObservableCollection<Customer> GetAll() 
{ 
    ObservableCollection<Customer> customers = new ObservableCollection<Customer>(); 

    XDocument xmlDoc = XDocument.Load(Customer.GetXmlFilePathAndFileName()); 
    var customerObjects = from customer in xmlDoc.Descendants("customer") 
          select new Customer 
          { 
           Id = (int)customer.Element("id"), 
           FirstName = customer.Element("firstName").Value, 
           LastName = customer.Element("lastName").Value, 
           Age = (int)customer.Element("age") 
          }; 
    foreach (var customerObject in customerObjects) 
    { 
     Customer customer = new Customer(); 

     customer.Id = customerObject.Id; 
     customer.FirstName = customerObject.FirstName; 
     customer.LastName = customerObject.LastName; 
     customer.Age = customerObject.Age; 

     customers.Add(customer); 
    } 

    return customers; 
} 
<DockPanel> 
    <ListBox ItemsSource="{Binding GetAll}" 
      ItemTemplate="{StaticResource allCustomersDataTemplate}" 
      Style="{StaticResource allCustomersListBox}"> 
    </ListBox> 
</DockPanel> 
GetAll()はViewModelのObservableCollectionプロパティです。 はObservableCollectionを満たすためにXMLファイルを読み取るGetAll()モデルメソッドを呼び出します。

これはすべてユーザーが別のビューに移動したときを除いてすべて正常に動作しますが、はXMLファイルを編集して戻ってきます古いデータがまだを表示しています。

どのように私は実際のデータを表示するように、このビューは "バインディングを更新する"と言うことができます。

あまりにも多くのHTML/HTTPのメタファーを使ってWPFについて説明しているような気がしますが、ObservableCollection自体を更新するためのより自然な方法があります。 WPFアプリケーションでデータを編集できるようにすることができます。だから、どんなレベルのヘルプもここで評価されます。

答えて

12

ItemsControlは、そのバインディングを1回要求し、その後で参照をキャッシュします。

コレクションオブジェクトの内容が変更され、INotifyCollectionChangedObservableCollectionと同じ)が実装されている場合は、追加または削除されたオブジェクトが選択されます。今

、あなたはバインディングがListBoxに新しいコレクションオブジェクトを提供したい場合、あなたはあなたのビューモデルがINotifyPropertyChangedを実装し、プロパティ名としてGetAllに渡し、PropertyChangedを上げることができます。 プロパティ値が変更されたことをバインディングに警告する効果があります(新しいObservableCollectionを取得する準備ができています)。ListBoxに供給され、アイテムを再生成します。

ObservableCollectionGetAllで返されているため、アプリからの変更を反映する限り、追加と削除が可能で、リストの同期は維持されます。外部の変更を取りたいとき(どこかにリフレッシュボタンがあるか、またはファイル全体をリロードするのが理にかなっているかもしれません)、ビューモデルがPropertyChangedイベントを呼び出すと、自動的にプロパティが呼び出されますgetterは静的メソッドを呼び出し、新しく新しいコレクションを返します。

Nitpicker note:プロパティにメソッド名を付ける理由は何ですか?私たちは、コレクション内のオブジェクトを追加するために削除したときと同じライン作業の下

+0

私がGETALL、感謝するのgetAll()を変更しました。問題は、それぞれ別々のGetAll ObservableCollectionをそれぞれのViewModelから取得する2つのビューがあり、ObservableCollectionが1つ変更されたときにもう1つが変更されないことです。どこかでこれらを世界中に保管する必要がありますか? –

+0

編集中に両方のビューが同期されると想定されている場合は、同じオブジェクトを何らかの方法で共有する必要があります。 あなたの場合、コレクションをロードしてキャッシュするデータアクセスシステムが存在する可能性があり、各ViewModelは現在のコレクションを要求します。そうすれば、両者は互いの変更を認識します。 ファイルからコレクションをリロードする必要がある場合は、コレクションオブジェクトが変更されたことをすべてのビューモデルに警告し、新しい参照を取得したらPropertyChangedイベントを発生させる方法があります。 –

+0

だから私のソリューションは、ユーザーコントロール(ビュー)が読み込まれるたびに、DataSourceをリフレッシュするように、素晴らしい、ありがとう! –

0

ObservableCollectionへの参照と、XMLファイルの最後の変更時刻をロードした時点での参照を保持します。ウィンドウがフォーカスを取得するたびに、ディスクファイルのタイムスタンプをチェックします。変更されている場合は、ObservableCollectionをクリアして再入力してください。 GUIはObservableCollectionからの変更イベントを自動的にリッスンし、コレクションの内容を変更すると自動的に再設定されます。

7

CollectionViewSource.GetDefaultView(CustomObservableCollection).Refresh(); 
関連する問題