0

MVVM パターン (および「シンプルな mvvm ツールキット」) と RIA サービス (およびサーバー側の EntityFramework) を使用して、ビューで Silverlight 4 データフォームを使用しています。

私のデータフォームは、viewModel の PagedCollectionView にバインドされています。論理的なコンテキストは、「「地域」には*「地域」があり、「地域」は「地域」にリンクされています」です(それを説明するために、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」イベントをリッスンして、PagedCollectionView の変更を監視し、DomainContext (「serviceAgent」を介して) を更新します。

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」が空である場合(Territoriesが存在しない場合)、アイテムを追加してから直接キャンセルすると、キャンセルアクションにより「case NotifyCollectionChangedAction.Remove:」が期待どおりに渡されます. 「this.CurrentRegion.Territories.Remove(territory);」まですべてが機能します。このコード行は、「'System.NullReferenceException' が System.Windows.Controls.Data.DataForm.Toolkit で発生する」を作成します。例外は、「this.RaiseDataMemberChanged("RegionID");」に正確に追加されます。「テリトリー」エンティティが内部更新を行っている場合: .

    /// <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」が最初に空でない場合、すべてが正常に機能することです...

私が間違っていることは何ですか?

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

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

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

助けてくれてありがとう!

4

1 に答える 1

0

この回答は、問題を解決するのに役立ちます: フィルターを PagedCollectionView に適用するが、編集時に CollectionChanged イベントが発生しないようにする方法は?

解決策は、PagedCollectionView の CollectionChanged イベントをリッスンするのではなく、PagedCollectionView.SourceCollection の CollectionChanged イベントをリッスンすることです。

したがって、コードは次のようになります。

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

ブライアントの助けに感謝し、Stackoverflow に感謝します!

于 2012-04-26T07:38:16.160 に答える