2011-05-22 8 views
1

MVVMプロジェクトにViewModelがあり、検索を開始したときにデータが非同期で読み込まれるWPFViewにバインドされています。 検索したデータには、異なる日に購入した同じ商品の価格が含まれています。 私のリストボックスのアイテムは価格で昇順に並べる必要があります。私のBackgroundWorkerがアイテムを返すとすぐに、それらはリストボックスに非同期で追加され、価格で注文され、すぐに捕らえられるようになります。WPFリストボックスのItemsSourceをObservableCollectionから<T>をMVVMの実行時にCollectionViewSourceに切り替える

私が見つけた優れたソリューションは、ViewModelにObservableCollectionを持っていて、それをListBoxのItemsSourceにバインドしています。 私はasynch検索を開始するBackgroundWorkerを持っています。私は、検索を実行し、オブジェクトのDataReceivedイベントハンドラに加入していると私はこのようにUIに通知:ディスパッチャ

private readonly Dispatcher _currentDispatcher; 

void sniper_DataReceived(object sender, TEventArgs e) 
    { 
     Action dispatchAction =() => this.Results.Add(e.T); 
     _currentDispatcher.BeginInvoke(dispatchAction); 
    } 

これは私にはOKと思われるが、私が必要とするアイテムを注文しないので、私はthet CollectionViewSourceが私が簡単な方法で必要なものを正確に行うことがわかりました。

ここでそれが問題です:

私はCollectionViewSourceに私のリストボックスののDataContextを設定した場合、私はあまり設計時のパワーを持って、私は私のリストボックスに私のデザイン時データを見ておくが、私は、データでのDataContextを失いますブレンドのタブ。

ax:Name属性でListBoxという名前を付け、MainWindow.xamlに後ろにコードを追加して、実行時に自分の名前付きリストボックスのデータソースをスワップするようにしました。この:

public MainWindow() 
    { 
     InitializeComponent(); 
     Closing += (s, e) => ViewModelLocator.Cleanup(); 

     #region CollectionViewSource Escamotage 
     if (!ViewModelLocator.MainStatic.IsInDesignMode) 
     { 
      var cvs = new CollectionViewSource() { Source = ViewModelLocator.MainStatic.Results }; 
      cvs.SortDescriptions.Add(new SortDescription("LowestPrice", ListSortDirection.Ascending)); 
      this.TrainsListBox.ItemsSource = cvs.View; 
     } 
     #endregion 
    } 

あなたはそれが罪とみなすことができると思いますか?

+0

これがうまくいけば幸せになれば、私はなぜそれが「罪」と考えられるのか分かりません;) – AbdouMoumen

答えて

1

collectionviewのソースをobservablecollecionにバインドすることができます。私の質問は:mvvmを使用している場合、なぜコードビハインドのように見えるのですか?

のViewModelコンストラクタ:

public PrimarySearchViewModel() 
      { 
       this.SearchResultsCVS = new CollectionViewSource(); 

       if (IsInDesignMode) 
       { 
        DesignMode_CreateSearchResults(); 

        // Code runs in Blend --> create design time data. 
       } 
       else 
       { 
        //Messenger.Default.Register<IEnumerable<ReadmitPatientList>>(this, MessageTypes.EXECUTESEARCHREQUEST, RefreshSearchResults); 
        //Messenger.Default.Register<MessageTypes.EXECUTESEARCHREQUEST>>(this,ICollection<ReadmitPatientList>,RefreshSearchResults); 
        Messenger.Default.Register<Messages.DisplayReadmitPatientListMessage>(this, onReciveDisplayReadmitPatientListMessage); 
        Messenger.Default.Register<WavelengthIS.Core.Messaging.SaveNotification<QuestionairreViewModel>>(this, sn => ClearSearchResults()); 
        // Code runs "for real": Connect to service, etc... 
       } 

      } 

は、私は通常私の設計時のデータを作成するために設計時のサービスを使用しますが、この場合には、私はちょうどでした間に合わせのコピー&ペースト:私が使用

private void DesignMode_CreateSearchResults() 
      { 
       this.SearchResults = new ObservableCollection<ReadmitPatientListViewModel>(); 

       this.SearchResults.Add(new ReadmitPatientListViewModel(new ReadmitPatientList() 
       { 
        PatientID = 0000000, 
        PatientName = "Test Patient", 
        PatientDOB = Convert.ToDateTime("01/01/2010"), 
        OriginalAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        OriginalReason = "Becauselkahsdfkahsfkahsf", 
        OriginalVisitNumber = "0000000", 
        ReAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        ReAdmitReason = ";aasfkahsfashfa;lsfas", 
        ReAdmitVisitNumber = "9999999" 
       } 
        )); 
       this.SearchResults.Add(new ReadmitPatientListViewModel(new ReadmitPatientList() 
       { 
        PatientID = 0000000, 
        PatientName = "Test Patient", 
        PatientDOB = Convert.ToDateTime("01/01/2010"), 
        OriginalAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        OriginalReason = "Becauselkahsdfkahsfkahsf", 
        OriginalVisitNumber = "0000000", 
        ReAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        ReAdmitReason = ";aasfkahsfashfa;lsfas", 
        ReAdmitVisitNumber = "9999999" 
       } 
        )); 
       this.SearchResults.Add(new ReadmitPatientListViewModel(new ReadmitPatientList() 
       { 
        PatientID = 0000000, 
        PatientName = "Test Patient", 
        PatientDOB = Convert.ToDateTime("01/01/2010"), 
        OriginalAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        OriginalReason = "Becauselkahsdfkahsfkahsf", 
        OriginalVisitNumber = "0000000", 
        ReAdmitDate = Convert.ToDateTime("01/01/2010 00:00:00"), 
        ReAdmitReason = ";aasfkahsfashfa;lsfas", 
        ReAdmitVisitNumber = "9999999" 
       } 
        )); 

       SearchResultsCVS_Refresh(); 
      } 
private void SearchResultsCVS_Refresh() 
     { 
      SearchResultsCVS.Source = this.SearchResults; 
      SearchResultsCVS.SortDescriptions.Clear(); 

      SearchResultsCVS.SortDescriptions.Add(new System.ComponentModel.SortDescription("PatientLastName", System.ComponentModel.ListSortDirection.Ascending)); 

      SearchResultsCVS.View.Refresh(); 
     } 

ViewModelsのObservableCollectionsです。 OCの通知イベントは、実際のリストアイテムのVMを使用してコレクションに追加または削除されたアイテムに対してのみ発生し、必要に応じてアイテムプロパティの変更通知を受け取ります。

また、ViewModelLocatorの設定が正しく、正しいことを確認する必要があります。私はMVVMLightを使用している人のいくつかの投稿を見つけましたが、そこから最も強力な機能のいくつかを使用していません。それを使用するように設計されたものとして使用すると、それは動作するように動作します...私はそれを証明することができます。

<!--Global View Model Locator--> 
        <local:ViewModelLocator x:Key="Locator" 
              d:IsDataSource="True" /> 

私は、IsDataSource属性が、BlendにDataTabに置くように指示すると信じています。しかし、私はDatamanulationのためにそれほど混じり合っていないので、私はそれについて心配していません。

関連する問題