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」が最初に空でない場合、すべてが正常に機能することです...
私が間違っていることは何ですか?
コードの詳細については、ソリューションのダウンロード リンク:
ソリューションを起動し、「地域」ページに移動し、リストの最後の項目のボタンをクリックします (地域は 0 に等しい)。そして、データフォームの子ウィンドウでキャンセルをクリックします。これにより、バグが発生するはずです。
助けてくれてありがとう!