Silverlight, ошибка с Dataform при добавлении, а затем удалении объекта с помощью PagedCollectionView?
Я использую форму данных silverlight 4 в представлении с шаблоном MVVM (и "простым инструментарием mvvm") и службами RIA (и EntityFramework на стороне сервера).
Моя форма данных - это привязка к PagedCollectionView в viewModel. Логический контекст таков: "Регион" имеет * "Территории", а "Территория" связана с "Регионом" "(я объясняю исходную проблему в базе данных 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);
Я наблюдаю изменения в PagedCollectionView для обновления моего DomainContext (через "serviceAgent"), прослушивая событие "CollectionChanged":
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" пусто (нет территорий), и если я добавляю элемент, а затем напрямую отменяю его, действие отмены заставляет меня передать "case NotifyCollectionChangedAction.Remove:", как и ожидалось., Все работает, пока 'this.CurrentRegion.Territories.Remove (территория);' эта строка кода создает "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). А затем нажмите "Отмена" в дочерних окнах формы данных. Это должно сделать ошибку появляется.
Спасибо за любую помощь!
1 ответ
Этот ответ поможет мне решить проблему: как применить фильтр к PagedCollectionView, но предотвратить запуск события CollectionChanged при редактировании?
Решением является не прослушивание события CollectionChanged объекта PagedCollectionView, а прослушивание события CollectionChanged объекта PagedCollectionView.SourceCollection.
Итак, код становится:
ObservableCollection<Territory> territories = new ObservableCollection<Territory>(this.CurrentRegion.Territories);
this.RegionTerritories = new PagedCollectionView(territories);
territories.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(RegionTerritories_CollectionChanged);
Спасибо за помощь, Брайант, и спасибо Stackru!