0

私はWPFの初心者です。私はM-V-VMソリューションを実装し、UIに反映する必要があるすべてのプロパティに対してINotifyPropertyChangedを実装しました。これまでのところ、すべてのものが正常に動作しているように見えますが、観察可能なコレクションを返す読み取り専用プロパティにバインドされたリストボックスを除きます。ListBoxをバインドすると、InotifyPropertyChangedでもObservableCollectionがスワップされません。

ViewModelBaseはINotifyPropertyChangedインターフェイスを実装しています:

public abstract class ViewModelBase : INotifyPropertyChanged 
{ 
    ..... 
    INotifyPropertyChanged Implementation 
    ..... 

    OnPropertyChanged(...) 
    { 
     ..... 
    } 
} 

MainViewModelクラスはViewModelBaseを継承し、UI(ビュー)のデータを保持しています。 BackgroundWorkerは、UserViewModelオブジェクトを作成します。オブジェクトはObservableCollectionに追加されます。 ListBoxは、UserViewModel ObservableCollectionを表示します。

Userオブジェクトが作成されるとき、それはObservableCollectionに追加され、OnPropertyChangedが呼び出されて、更新するようにUI要素に通知します。これは正常に動作します。

ユーザーがお気に入りのみを表示するように選択すると、表示されている1つのユーザーアイテムが削除されます。 Check &チェックボックスのチェックを外すと同じ効果があります。つまり、ユーザアイテムがリストビューから削除されます。予想される動作は、観測可能なコレクション間で切り替えることです。

public class MainViewModel : ViewModelBase 
{  
    private ObservableCollection<UserViewModel> mUsers = new ObservableCollection<UserViewModel>(); 
    private ObservableCollection<UserViewModel> mFavoriteUsers = new ObservableCollection<UserViewModel>(); 
    UserViewModel mSelectedUser; 
    private bool mbShowFavorite; 

    public bool ShowFavorite 
    { 
     get { return this.mbShowFavorite; } 
     set 
     { 
      this.mbShowFavorite = value; 
      OnPropertyChanged("ShowFavorite"); 
      OnPropertyChanged("Users"); 
     } 
    } 

    public UserViewModel SelectedUser 
    { 
     get { return this.mSelectedUser; } 
     set 
     { 
      this.mSelectedUser = value; 
      OnPropertyChanged("SelectedUser"); 
     } 
    } 

    public ObservableCollection<UserViewModel> Users 
    { 
     get 
     { 
      if (this.mbShowFavorite) 
       return this.mFavoriteUsers; 
      else 
       return this.mUsers; 
     } 
    } 

    ..... 
    Other Class Members 
    ..... 

    void BackgroundCreateUserModelsCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // Add the User View Model 
     this.mUsers.Add((UserViewModel)e.Result); 

     if (((UserViewModel)e.Result).IsFavorite) 
     { 
      this.mFavoriteUsers.Add((UserViewModel)e.Result); 
     } 

     // Users changed: Notify Property Changes 
     OnPropertyChanged("Users"); 
    } 
} 

ここに、上記のコードに関連するXAMLビューがあります。

<CheckBox VerticalAlignment="Center" Content="Show Favorites" 
    IsChecked="{Binding Path=ShowFavorite, Mode=TwoWay}" /> 

<ListBox Name="listboxUsers" 
    ItemsSource="{Binding Path=Users}" 
    SelectedItem="{Binding SelectedUser, Mode=TwoWay}">    
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <views:UserView></views:UserView> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox>  

私の質問は、どのように動作させるかです。私はお気に入りのチェックボックスがチェックされているかどうかに基づいてビューを入れ替える必要があります。

答えて

0

問題は、コレクションの変更がUIスレッドにマーシャリングされていないことに関連している可能性があります。詳細はMaking sure OnPropertyChanged() is called on UI thread in MVVM WPF appを参照してください。

+0

ご返信ありがとうございます...残念ながら、これは役に立ちません。 OnPropertyChanged()はUIスレッドで呼び出されます。リストが最初に表示される方法です。問題はコレクション間の切り替えです。コレクションを切り替えると、リスト項目が1つずつ消えます。 – Gaurav

+0

どこかで問題を再現するソースをアップロードできますか? – devdigital

+0

こんにちは、フォローアップのおかげで、問題を再現するサンプルプロジェクトを作成しようとしました。しかし、そのプロジェクトでも同じことが働きます。私は実際のプロジェクトで何か不足しているかもしれません。ご参考までに、ここにサンプルがあります:http://db.tt/pQdrSzO – Gaurav

関連する問題