【问题标题】:Silverlight, bug with Dataform when adding and then removing entity with PagedCollectionView?Silverlight,在使用 PagedCollectionView 添加然后删除实体时出现 Dataform 错误?
【发布时间】:2012-04-25 13:59:39
【问题描述】:

我在具有 MVVM 模式(和“简单的 mvvm 工具包”)和 RIA 服务(以及服务器端的 EntityFramework)的视图上使用 silverlight 4 数据表单。

我的数据表单绑定到 viewModel 上的 PagedCollectionView。逻辑上下文是“A 'Region' has * 'Territories' and a 'Territory' is linked to a '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”事件来观察 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”为空(不存在任何领土),并且如果我添加一个项目然后直接取消它,取消操作会让我传递“case NotifyCollectionChangedAction.Remove: “正如预期的那样。一切正常,直到'this.CurrentRegion.Territories.Remove(territory);'这行代码创建了一个“System.Windows.Controls.Data.DataForm.Toolkit 上发生'System.NullReferenceException'”。异常附加在 "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

Lauch 解决方案,进入“地区”页面,然后单击列表中最后一项的按钮(地区为 0)。然后单击数据窗体的子窗口上的取消。这应该会出现错误。

感谢您的帮助!

【问题讨论】:

  • 我下载了您的解决方案,并在测试时运行良好。但是,我使用的是 Silverlight 5。
  • 您好!感谢您的回答 !我尝试使用 Silverlight 5。问题仍然存在。你到底尝试了什么?
  • 我刚刚打开了您的项目并按照您的说明进行操作,没有收到任何错误。
  • 好的,这很奇怪...我现在找到了解决方案,但还是感谢您的帮助!

标签: silverlight ria dataform pagedcollectionview


【解决方案1】:

这个答案帮助我解决问题: How to apply a Filter to a PagedCollectionView but prevent CollectionChanged event from firing on edit?

解决方法是不监听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);             

感谢 Bryant 的帮助,也感谢 Stackoverflow!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多