c# - 使用 SummaryRow 和分组时 Syncfusion SfDataGrid 崩溃

标签 c# ios datagrid xamarin.ios syncfusion

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

我正在使用数据网格的分组和摘要行功能来创建自定义分组标题文本消息。在我的解决方案中,这在 Debug模式下没有任何问题,当我在 Release模式下运行应用程序时,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 更新,以便分组摘要行反射(reflect)动态变化到底层数据源):

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);
}

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

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 提交了一张票来调查它,但是如果有人有使用这个组件的经验并使用过我试图成功使用的功能,那将是非常有助于获得一些意见。

更新:

我看到的初始错误实际上已通过为发布和调试设备构建使用链接器跳过标志得到修复。

设置项目选项 > 构建 > iOS 构建 > 附加 mtouch 参数(用于 Release/iPhone 和 Debug/iPhone 目标)到 --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 使用了反射。默认情况下,在 Release模式下,iOS 应用程序会通过链接过程,该过程使用静态分析找出所有可能使用的代码路径并删除所有未使用的代码,但此过程无法遵循在运行时使用反射动态创建的路径,因此如果您使用在您的项目上进行任何类型的链接 SfDataGrid 的某些功能(如我的情况)将不起作用并导致崩溃。

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

项目选项 > 构建 > iOS 构建 > 链接器行为:“不链接”

结论

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

最佳答案

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

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

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

如果您在尝试知识库文章中提到的步骤后仍能重现问题,请向我们提供相同的复制示例,以便我们尽快解决您的问题并更好地帮助您。

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

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

关于c# - 使用 SummaryRow 和分组时 Syncfusion SfDataGrid 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42658008/

相关文章:

c# - 如何获取 WPF DataGrid 选定的单元格值?

ios - 访问 IOS 数组和字典中包含的值

ios - 新应用和应用更新必须使用 Xcode 6 或更高版本、OS X 和 iOS SDK 的公共(public) (GM) 版本构建

iphone - iOS 4.3、iPhone 4 不使用 UILocalNotification 播放自定义声音

c# - 无法使用多重绑定(bind)绑定(bind) DataGrid ItemsSource - 简单绑定(bind)工作正常

c# - 如何统计我的列的总数?

c# - 使用 Firefox 43 及更高版本创建新的 FirefoxDriver 再次超时

c# - 将 TCP StreamReader/StreamWriter 转换为 SSLStream

c# - Windows 应用商店应用程序中的 Grid.ShowGridLines

c# - ASP.NET MVC - [Bind(Exclude = "Id")] 的替代方法