2012-04-25 2 views
0

私は、MVVMパターン(および "単純なmvvmツールキット")とRIAサービス(およびサーバー側のEntityFramework)を持つビューでSilverlight 4データフォームを使用しています。Silverlight、PagedCollectionViewを使用してエンティティを追加して削除すると、Dataformのバグ?

私のデータフォームは、viewModelのPagedCollectionViewにバインドします。論理的なコンテキストは "A 'Region'には* 'Territories'があり、 'Territory'には 'Region' 'がリンクされています"(Nothwindデータベースの元の問題を再現して説明します)。

<toolkit:DataForm Name="DataForm" 
           ItemsSource="{Binding RegionTerritories}" 
           CurrentItem="{Binding TerritorySelected, Mode=TwoWay}" 
           AutoGenerateFields="True" 
           AutoEdit="True" 
           AutoCommit="False" 
           IsReadOnly="False" 
           Margin="0,10,0,0" EditEnded="DataForm_EditEnded" 
           DeletingItem="DataForm_DeletingItem" AddingNewItem="DataForm_AddingNewItem" 
           CurrentItemChanged="DataForm_CurrentItemChanged" /> 

pagedCollectionViewにエンティティをロードするために、私のビューモデルのコード:

this.RegionTerritories = new PagedCollectionView(this.CurrentRegion.Territories.ToList());     
      this.RegionTerritories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(RegionTerritories_CollectionChanged); 

私は「て、CollectionChanged」イベントを聞くことによって、私のDomainContext(throught「serviceAgent」)を更新するPagedCollectionView上の変更を監視:

private void RegionTerritories_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     switch (e.Action) 
     { 
      case NotifyCollectionChangedAction.Add: 
       foreach (var item in e.NewItems) 
       { 
        Territory territory = item as Territory; 
        if (territory != null) 
        { 
         this.regionServiceAgent.InitializeNewTerritoryAndAddToDomainContext((Territory)item); 
         territory.Region = this.CurrentRegion; 
         this.CurrentRegion.Territories.Add(territory);        
        } 
       } 
       break; 
      case NotifyCollectionChangedAction.Remove: 
       foreach (var item in e.OldItems) 
       { 
        Territory territory = item as Territory; 
        if (territory != null) 
        { 
         if (this.CurrentRegion.Territories.Contains<Territory>(territory)) 
         { 
          this.regionServiceAgent.MarkForDeleteTerritory(territory); 
          this.CurrentRegion.Territories.Remove(territory);        

         } 
        } 
       } 
       break; 
      //case NotifyCollectionChangedAction.Replace: 
      // break; 
      //case NotifyCollectionChangedAction.Reset: 
      // break; 
     } 
    } 

そしてここでは私の問題である:「this.CurrentRegion.Territories」が空の場合(無領土存在)、と私はアイテムを追加して、直接cance場合それで、キャンセルアクションは "case NotifyCollectionChangedAction.Remove:"を期待どおりに渡すようにします。すべては 'this.CurrentRegion.Territories.Remove(territory);'まで動作します。このコード行では、System.Windows.Controls.Data.DataForm.Toolkitで "'System.NullReferenceException'が発生します。 Exceptionは "this.RaiseDataMemberChanged(" RegionID ");" "Territory"エンティティが内部更新を行っているとき:。

/// <summary> 
    /// Obtient ou définit la valeur « RegionID ». 
    /// </summary> 
    [DataMember()] 
    [RoundtripOriginal()] 
    public int RegionID 
    { 
     get 
     { 
      return this._regionID; 
     } 
     set 
     { 
      if ((this._regionID != value)) 
      { 
       this.OnRegionIDChanging(value); 
       this.RaiseDataMemberChanging("RegionID"); 
       this.ValidateProperty("RegionID", value); 
       this._regionID = value; 
       this.RaiseDataMemberChanged("RegionID"); // THIS CAUSE DATAFORM FAIL !! 
       this.OnRegionIDChanged(); 
      } 
     } 
    } 

奇妙なことは、もし「this.CurrentRegion.Territoriesは」初めに空ではないということですeveythingが正常に動作します...間違って何I'am

コードの詳細についてソリューションのダウンロードリンク:

https://skydrive.live.com/redir.aspx?cid=e41cfc4c2d6196d4&resid=E41CFC4C2D6196D4!252&parid=E41CFC4C2D6196D4!215&authkey=!AALulK7qBi40vJk

出せソリューション、「地域」ページに移動し、リストの最後の項目のボタンをクリックします(領土では0に等しいです。 )。そして、データフォームの子ウィンドウでキャンセルをクリックします。これにより、バグが表示されます。

ありがとうございました!

+0

私はあなたのソリューションをダウンロードし、それをテストしたところ正常に動作しました。しかし、私はSilverlight 5を使用しています。 – Bryant

+0

こんにちは!ご回答有難うございます !私はSilverlight 5を使ってみる。問題はまだここにある。何を正確に試しましたか? – Ben

+0

私はあなたのプロジェクトを開いてあなたの指示に従いましたが、何の誤りもありませんでした。 – Bryant

答えて

0

この回答は問題を解決するために私を助ける: How to apply a Filter to a PagedCollectionView but prevent CollectionChanged event from firing on edit?

ソリューションはPagedCollectionViewのて、CollectionChangedイベントに耳を傾けないように、しかしPagedCollectionView.SourceCollectionのて、CollectionChangedイベントに耳を傾けることです。

ので、コードは次のようになります。ヘルプブライアント、と感謝のStackOverflowのため

ObservableCollection<Territory> territories = new ObservableCollection<Territory>(this.CurrentRegion.Territories); 
this.RegionTerritories = new PagedCollectionView(territories); 
territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(RegionTerritories_CollectionChanged);    

ありがとう!

関連する問題