将自定义 UITableViewCell 与 ViewCellRenderer 一起使用时出现 NullReferenceException

Posted

技术标签:

【中文标题】将自定义 UITableViewCell 与 ViewCellRenderer 一起使用时出现 NullReferenceException【英文标题】:NullReferenceException when using custom UITableViewCell with ViewCellRenderer 【发布时间】:2017-01-17 16:56:37 【问题描述】:

我正在尝试设置一个测试项目,在该项目中,我在 Xamarin.Forms ListView 中使用特定于平台的实现来实现 ViewCell。在 UWP 中,一切都按预期工作。但是当我尝试在 ios 模拟器上打开该页面时。我在没有任何其他提示的情况下检索 NullReferenceException:

UIApplication.Main(args, null, "AppDelegate");

这当然没有多大帮助。

Forms XAML 看起来像这样:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             xmlns:controls="clr-namespace:My.Controls;assembly=My.Controls"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="PrismFormsPrototype.Views.TestPage">
    <StackLayout HorizontalOptions="StartAndExpand" VerticalOptions="StartAndExpand">
        <ListView x:Name="PlatformSpecificCellsList"  
                  CachingStrategy="RecycleElement" 
                  BindingContext="Binding MyCompanies" 
                  ItemsSource="Binding Companies" BackgroundColor="Gray">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <controls:TileCell Text="Binding Text" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

而且本地单元的实现也非常容易监督:

internal class NativeTileCell : UITableViewCell, INativeElementView

    public UILabel HeadingLabel  get; set; 
    public TileCell TileCell  get; private set; 
    public Element Element => TileCell;

    public NativeTileCell(string cellId, TileCell cell) : base(UITableViewCellStyle.Default, cellId)
    
        TileCell = cell;

        SelectionStyle = UITableViewCellSelectionStyle.Gray;
        ContentView.BackgroundColor = UIColor.FromRGB(255, 255, 224);

        HeadingLabel = new UILabel()
        
            Font = UIFont.FromName("Cochin-BoldItalic", 22f),
            TextColor = UIColor.FromRGB(127, 51, 0),
            BackgroundColor = UIColor.Clear
        ;

        ContentView.Add(HeadingLabel);
    

    public void UpdateCell(TileCell cell)
    
        HeadingLabel.Text = cell.Text;
    

    public override void LayoutSubviews()
    
        base.LayoutSubviews();

        HeadingLabel.Frame = new CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
    

在 NativeTileCellRenderer 中使用。

[assembly: ExportRenderer(typeof(TileCell), typeof(NativeTileCellRenderer))]
namespace My.Controls.iOS

    public class NativeTileCellRenderer : ViewCellRenderer
    
        NativeTileCell cell;

        public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
        
            var tileCell = item as TileCell;
            if (tileCell == null)
                return null;

            cell = reusableCell as NativeTileCell;
            if (cell == null)
                cell = new NativeTileCell(item.GetType().FullName, tileCell);
            else
                cell.TileCell.PropertyChanged -= OnNativeCellPropertyChanged;

            tileCell.PropertyChanged += OnNativeCellPropertyChanged;
            cell.UpdateCell(tileCell);
            return cell;
        

        private void OnNativeCellPropertyChanged(object sender, PropertyChangedEventArgs e)
        
            var tileCell = sender as TileCell;
            if (tileCell == null)
                return;

            if (e.PropertyName == TileCell.TextProperty.PropertyName)
                cell.HeadingLabel.Text = tileCell.Text;
        
    

我的断点都没有被命中。所以我真的不知道这个异常来自哪里。有人可以给我一个提示吗?我的代码基于此站点的教程:https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/viewcell/May the Information be to old??

我在 Visual Studio 2017RC 中使用 Xamarin.Forms 2.3.3.180。

干杯, 克里斯

更新:

“有趣”的行为:当我用 try/catch 包围 Main 调用时,我会检索有关异常的更多信息。这是异常堆栈的内容:

  at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00000] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Platform.cs:281 
  at Xamarin.Forms.Platform.iOS.ViewCellRenderer+ViewTableCell.GetNewRenderer () [0x00000] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Cells\ViewCellRenderer.cs:136 
  at Xamarin.Forms.Platform.iOS.ViewCellRenderer+ViewTableCell.UpdateCell (Xamarin.Forms.ViewCell cell) [0x0004e] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Cells\ViewCellRenderer.cs:155 
  at Xamarin.Forms.Platform.iOS.ViewCellRenderer+ViewTableCell.set_ViewCell (Xamarin.Forms.ViewCell value) [0x0000a] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Cells\ViewCellRenderer.cs:65 
  at Xamarin.Forms.Platform.iOS.ViewCellRenderer.GetCell (Xamarin.Forms.Cell item, UIKit.UITableViewCell reusableCell, UIKit.UITableView tv) [0x0004d] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Cells\ViewCellRenderer.cs:22 
  at Xamarin.Forms.Platform.iOS.CellTableViewCell.GetNativeCell (UIKit.UITableView tableView, Xamarin.Forms.Cell cell, System.Boolean recycleCells, System.String templateId) [0x00086] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Cells\CellTableViewCell.cs:74 
  at Xamarin.Forms.Platform.iOS.ListViewRenderer+ListViewDataSource.GetCell (UIKit.UITableView tableView, Foundation.NSIndexPath indexPath) [0x00060] in C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:727 
  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/a7f1dc3d/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/a7f1dc3d/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
  at PrismFormsPrototype.iOS.Application.Main (System.String[] args) [0x00002] in C:\Workspace\PrismFormsPrototype\PrismFormsPrototype\PrismFormsPrototype.iOS\Main.cs:19 

解决方案:

我发现了问题。我使用类库进行控制。在编译期间,编译器删除了对该类库的引用,因为它没有识别出对该类库的任何使用。所以我用一个虚拟方法编写了一个静态虚拟类,现在从主 iOS 应用程序中调用它。现在他可以找到客户渲染器了。

【问题讨论】:

能否请您为您的ListView 发布完整的 XAML?您需要记住定义local 条目,然后将该声明用于您的DataTemplate,如here 所述。即:&lt;local:TitleCell .... /&gt;. @Demitrian,我更新了 xaml 页面的其余部分。我不认为 xaml 是问题所在。它在 UWP 下按预期工作。问题似乎是iOS平台上iOS Renderer的构建! 【参考方案1】:

我发现了问题。我使用类库进行控制。在编译期间,编译器删除了对该类库的引用,因为它没有识别出对该类库的任何使用。所以我用一个虚拟方法编写了一个静态虚拟类,现在从主 iOS 应用程序中调用它。现在他可以找到客户渲染器了。

【讨论】:

以上是关于将自定义 UITableViewCell 与 ViewCellRenderer 一起使用时出现 NullReferenceException的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义uitableviewcell一一附加到uitableview

将自定义 UITableViewCell 从 nib 加载到 Swift 中的 UIViewController

如何将自定义单元格连接到 UIViewController?

将自定义 UIView 添加到 TableViewCell

拆分视图控制器 - 自定义 UITableViewCell

labview中啥是严格类型VI,怎样创建严格类型VI