使用SummaryRow和分组

时间:2017-03-07 20:46:16

标签: c# ios datagrid xamarin.ios syncfusion

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

我正在利用datagrid的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更新,以便分组摘要行反映动态更改到底层数据源):

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

UPDATE:

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

设置项目选项&gt;构建&gt; iOS Build&gt;其他mtouch参数(对于Release / iPhone和Debug / iPhone目标)到--linkskip=System.Core

这解决了“System.Linq.Queryable”类型中存在“No method'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 > Build > iOS Build > Linker behavior: "Don't Link"

结论

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

1 个答案:

答案 0 :(得分:3)

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

KB Link: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平台的问题和解决方案是相同的。

如果您在尝试KB中提到的步骤后仍能够重现该问题,请使用相同的复制样本还原我们,以便我们能够最快地解决您的问题,并帮助您做得更好。

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

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