Silverlight, ошибка с Dataform при добавлении, а затем удалении объекта с помощью PagedCollectionView?

Я использую форму данных silverlight 4 в представлении с шаблоном MVVM (и «простым набором инструментов mvvm») и службами RIA (и EntityFramework на стороне сервера).

Моя форма данных привязана к 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);

Я наблюдаю за изменениями в 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(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). Затем нажмите «Отмена» в дочерних окнах формы данных. Это должно привести к появлению ошибки.

Спасибо за любую помощь!


person Ben    schedule 25.04.2012    source источник
comment
Я скачал ваше решение, и оно работало нормально, когда я его тестировал. Однако я использую Silverlight 5.   -  person Bryant    schedule 25.04.2012
comment
Привет ! Спасибо за Ваш ответ ! Я пытаюсь использовать Silverlight 5. Проблема все еще здесь. Что именно вы пробовали?   -  person Ben    schedule 26.04.2012
comment
Я только что открыл ваш проект и следовал вашим инструкциям и не получил никаких ошибок.   -  person Bryant    schedule 26.04.2012
comment
Хорошо, это очень странно... Теперь я нашел решение, но все равно спасибо за помощь!   -  person Ben    schedule 27.04.2012


Ответы (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);             

Спасибо за помощь, Брайант, и спасибо Stackoverflow!

person Ben    schedule 26.04.2012