【问题标题】:Syncfusion SfDataGrid crashing when using SummaryRow and GroupingSyncfusion SfDataGrid 在使用 SummaryRow 和 Grouping 时崩溃
【发布时间】:2017-03-07 20:46:15
【问题描述】:

我在 iOS 应用程序中使用 Syncfusion Xamarin.iOS 库组件 SfDataGrid。

我正在利用数据网格的 Grouping 和 SummaryRow 功能来创建自定义分组标题文本消息。在我的解决方案中,这在调试模式下没有任何问题,当我在发布模式下运行应用程序时,Syncfusion 组件崩溃,并在我的 hockeyapp 崩溃日志中记录以下错误:

System.InvalidOperationException: No method 'OfType' exists on type 'System.Linq.Queryable'.

at System.Linq.Expressions.Expression.FindMethod (System.Type type, System.String methodName, System.Type[] typeArgs, System.Linq.Expressions.Expression[] args, System.Reflection.BindingFlags flags) <0x100bed560 + 0x00178> in <7e733344809544cdb96fb85d3fa04558#6766c6796a86a13adfcc8378724365f2>:0 
  at System.Linq.Expressions.Expression.Call (System.Type type, System.String methodName, System.Type[] typeArguments, System.Linq.Expressions.Expression[] arguments) <0x100beccb0 + 0x00083> in <7e733344809544cdb96fb85d3fa04558#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.Extensions.QueryableExtensions.OfType (System.Linq.IQueryable source, System.Type sourceType) <0x100f6ac80 + 0x00103> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.Extensions.QueryableExtensions.OfQueryable (System.Collections.IEnumerable items, System.Type sourceType) <0x100f6a820 + 0x0001f> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaryForBottomLevelGroup (Syncfusion.Data.Group group, Syncfusion.Data.ISummaryRow summaryRow) <0x100f53260 + 0x001a7> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaries (System.Collections.Generic.IEnumerable`1[T] groups, System.Int32 level, Syncfusion.Data.ISummaryRow summaryRow) <0x100f52070 + 0x000af> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaries (Syncfusion.Data.Group group, System.Int32 level, Syncfusion.Data.ISummaryRow summaryRow) <0x100f51f90 + 0x00063> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaries () <0x100f51e50 + 0x0009f> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv.InitializeTopLevelGroup () <0x100f34790 + 0x001ab> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv.RefreshTopLevelGroup () <0x100f349e0 + 0x00043> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv.EndDeferInternal () <0x100f306a0 + 0x001f3> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv.EndDefer () <0x100f30660 + 0x0001f> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv+DeferHelper.Dispose (System.Boolean isDisposing) <0x100f3a8a0 + 0x0003b> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.Data.CollectionViewAdv+DeferHelper.Dispose () <0x100f3a860 + 0x0001f> in <8945d0bafa9a4425bcee03773220107f#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.DeferRefresh () <0x100e65750 + 0x000f3> in <9c1c4744d92347f39b995b2a4b95a8bb#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.SetSourceList (System.Object source) <0x100e639b0 + 0x00033> in <9c1c4744d92347f39b995b2a4b95a8bb#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.RefreshContainerAndView () <0x100e66f60 + 0x00043> in <9c1c4744d92347f39b995b2a4b95a8bb#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.gridLoaded () <0x100e637d0 + 0x0014f> in <9c1c4744d92347f39b995b2a4b95a8bb#6766c6796a86a13adfcc8378724365f2>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.LayoutSubviews () <0x100e602a0 + 0x00033> in <9c1c4744d92347f39b995b2a4b95a8bb#6766c6796a86a13adfcc8378724365f2>:0 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) <0x10050b6f0 + 0x0002b> in <cc077ba5ca594b7b8b31455dce914ca4#6766c6796a86a13adfcc8378724365f2>:0 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) <0x10050b630 + 0x000ab> in <cc077ba5ca594b7b8b31455dce914ca4#6766c6796a86a13adfcc8378724365f2>:0

为了进一步解决这个问题,我尝试在 Grouping.cs 示例中由 syncfusion 提供的示例应用程序上测试我的代码(注意:在这种用法中,我在 GridLoaded 处理程序中启用了 SummaryRow 更新,以便 Grouping Summary Rows 反映动态变化到底层数据源):

public Grouping ()
{
    this.SfGrid = new SfDataGrid ();
    this.SfGrid.SelectionMode = SelectionMode.Single;
    this.SfGrid.ItemsSource = new GroupingViewModel ().ProductDetails;
    this.SfGrid.AutoGeneratingColumn += GridAutoGenerateColumns;
    this.SfGrid.GroupColumnDescriptions.Add (new GroupColumnDescription (){ ColumnName = "Product" });
    this.SfGrid.HeaderRowHeight = 45;
    this.SfGrid.RowHeight = 45;
    this.SfGrid.AllowGroupExpandCollapse = true;
    this.SfGrid.QueryRowHeight += SfGrid_QueryRowHeight;


    var summaryRow = new GridSummaryRow();
    summaryRow.Title = "    {Key} ({ProductCount}) {TotalPrice}";
    summaryRow.ShowSummaryInRow = true;
    summaryRow.SummaryColumns.Add(new GridSummaryColumn
    {
        Name = "TotalPrice",
        MappingName = "Price",
        Format = "{Sum:n}",
        SummaryType = SummaryType.DoubleAggregate
    });
    summaryRow.SummaryColumns.Add(new GridSummaryColumn
    {
        Name = "ProductCount",
        MappingName = "ProductType",
        Format = "{Count}",
        SummaryType = SummaryType.CountAggregate
    });
    this.SfGrid.CaptionSummaryRow = summaryRow;
    // enable summary row update
    this.SfGrid.GridLoaded += (object sender, GridLoadedEventArgs e) =>
    {
        if (this.SfGrid.View != null)
            this.SfGrid.View.LiveDataUpdateMode = LiveDataUpdateMode.AllowSummaryUpdate;
    };

    this.AddSubview (SfGrid);
}

然而,即使在调试模式下使用这段代码,此测试也会使应用程序崩溃:

var summaryRow = new GridSummaryRow();
summaryRow.Title = "    {Key} ({ProductCount}) {TotalPrice}";
summaryRow.ShowSummaryInRow = true;
summaryRow.SummaryColumns.Add(new GridSummaryColumn
{
    Name = "TotalPrice",
    MappingName = "Price",
    Format = "{Sum:n}",
    SummaryType = SummaryType.DoubleAggregate
});
summaryRow.SummaryColumns.Add(new GridSummaryColumn
{
    Name = "ProductCount",
    MappingName = "ProductType",
    Format = "{Count}",
    SummaryType = SummaryType.CountAggregate
});
this.SfGrid.CaptionSummaryRow = summaryRow;
// enable summary row update
this.SfGrid.GridLoaded += (object sender, GridLoadedEventArgs e) =>
{
    if (this.SfGrid.View != null)
        this.SfGrid.View.LiveDataUpdateMode = LiveDataUpdateMode.AllowSummaryUpdate;
};

这很可能是组件中的一个损坏的功能,我已经向 Syncfusion 提交了一张票来调查它,但如果有人有使用此组件的经验并使用我尝试成功使用的功能,那将是非常有助于获得一些意见。

更新:

我看到的最初错误实际上是通过在发布和调试设备构建中使用链接器跳过标志来修复的。

Setting Project Options > Build > iOS Build > Additional mtouch arguments (for Release/iPhone and Debug/iPhone targets) to --linkskip=System.Core

这解决了我看到的“类型 'System.Linq.Queryable' 上不存在方法 'OfType'”错误。


然而,此修复发现了另一个 Syncfusion 库错误:

Message: ColumnName cannot be NULL
Source: Syncfusion.Linq.iOS
StackTrace:
  at Syncfusion.Data.Extensions.PropertyDescriptorExtensions.GetPropertyDescriptor (System.ComponentModel.PropertyDescriptorCollection pdc, System.String columnName) [0x00003] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaryForGroup (Syncfusion.Data.Group group, Syncfusion.Data.ISummaryRow summaryRow) [0x00246] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaries (Syncfusion.Data.Group group, System.Int32 level, Syncfusion.Data.ISummaryRow summaryRow) [0x00009] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.TopLevelGroup.UpdateCaptionSummaries () [0x00044] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv.InitializeTopLevelGroup () [0x0006a] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv.RefreshTopLevelGroup () [0x00022] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv.EndDeferInternal () [0x0008c] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv.EndDefer () [0x00008] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv+DeferHelper.Dispose (System.Boolean isDisposing) [0x00014] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.Data.CollectionViewAdv+DeferHelper.Dispose () [0x00000] in <6f9d653653de4429a0f62ab48bee8a99>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.DeferRefresh () [0x00050] in <c3adc0ba74224f2691c435bf11ff9990>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.SetSourceList (System.Object source) [0x0000d] in <c3adc0ba74224f2691c435bf11ff9990>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.RefreshContainerAndView () [0x00026] in <c3adc0ba74224f2691c435bf11ff9990>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.gridLoaded () [0x00077] in <c3adc0ba74224f2691c435bf11ff9990>:0 
  at Syncfusion.SfDataGrid.SfDataGrid.LayoutSubviews () [0x00008] in <c3adc0ba74224f2691c435bf11ff9990>:0 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3985/35d1ccd0/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3985/35d1ccd0/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
  at SampleBrowser.Application.Main (System.String[] args) [0x00008] in /Users/dsamuylov/Documents/Syncfusion/15.1451.0.37/Xamarin/sample/iOS/SampleBrowser/Main.cs:19

解决方案

在 +1 Vimal Prabhu 的额外输入之后,我意识到这个问题的原因是 Syncfusion SfDataGrid 正在使用反射。默认情况下,在发布模式下,iOS 应用程序会通过链接过程,该过程使用静态分析来找出所有可能使用的代码路径并删除所有未使用的代码,但是这个过程不能遵循在运行时使用反射动态创建的路径,所以如果你使用对您的项目进行任何类型的链接,在我的情况下,SfDataGrid 的某些功能将不起作用并导致崩溃。

简短的解释。在发布版本中关闭链接:

Project Options &gt; Build &gt; iOS Build &gt; Linker behavior: "Don't Link"

结论

如果您想在 SfDataGrid 中使用全套功能,您将无法在您的发布版本中使用链接。就我而言,这将发布应用程序的大小增加了 50%,从 40mb 增加到 60mb。在我的情况下,这不是一个重大问题(企业部署的应用程序内部公司使用),对于规模更大的 AppStore 应用程序来说,这可能是一个重大且令人望而却步的变化。

【问题讨论】:

    标签: c# ios datagrid xamarin.ios syncfusion


    【解决方案1】:

    当链接器模式设置为 LinkFrameWorkSDK 时,您面临的可能是已知的 Xamarin 框架问题。请尝试以下知识库链接中提到的步骤。

    知识库链接:https://www.syncfusion.com/kb/5986/how-to-solve-system-methodmissingexception-in-xamarin-forms-ios-when-using-sfdatagrid

    请不要混淆上述知识库链接指向 Xamarin.Forms 平台而不是 Xamarin.iOS。幸运的是,Xamarin.Forms.iOS 和 Xamarin.iOS 平台的问题和解决方案是相同的。

    如果您在尝试 KB 中提到的步骤后仍能重现该问题,请使用相同的复制示例回复我们,以便我们能够尽快解决您的问题并为您提供更好的帮助。

    请参阅此 UG,其中包含有关摘要行的所有可能格式、聚合、自定义摘要等的详细描述以及示例

    UG链接:https://help.syncfusion.com/xamarin-ios/sfdatagrid/summary#formatting-summary

    【讨论】:

    • +1 第一个链接帮助解决了最初的错误。第二个链接没有提供使用 DataGrid 分组功能的工作版本,在 CaptionSummary 行上启用更新以反映对基础数据源的更改。请参阅已更新:关于 Syncfusion 组件仍在抛出的新错误的原始问题中的一部分。这是我的配置/使用错误还是库中的错误?
    • 将其标记为答案,因为我从 Vimal 收到的信息帮助我理解了问题并找到了解决方法,请参阅上面的解决方案:最终修复部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2014-10-06
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多