PrafulD PrafulD - 11 days ago 7
C# Question

CollectionView in Xamarin.Forms using custom renderers

I have Xaml form from which I an rendering the collection view

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:local="clr-namespace:CustomRenderer_POC;assembly=CustomRenderer_POC"
x:Class="CustomRenderer_POC.GalleryPage">
<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
<local:CollectionView/>
</ContentPage>


CollectionView.CS

using Xamarin.Forms;
namespace CustomRenderer_POC
{
public class CollectionView : ContentView
{

}
}


CollectionViewRender.cs (in iOS project)

using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;
using UIKit;
using CustomRenderer_POC;
using CoreGraphics;

[assembly: ExportRenderer(typeof(CollectionView), typeof(CollectionViewRenderer))]
namespace CustomRenderer_POC
{
class CollectionViewRenderer : ViewRenderer<CollectionView, UICollectionView>
{
protected override void OnElementChanged(ElementChangedEventArgs<CollectionView> e)
{
var layout = new UICollectionViewFlowLayout();
base.OnElementChanged(e);
if (Control == null)
SetNativeControl(new UICollectionView(new CGRect(0, 0, 300, 256), new UICollectionViewLayout()));
if (Control != null)
{
int[] a = new int[] {10, 11, 12, 13, 14};
Control.Source = new CollectionViewSource(a);
Control.BackgroundColor = UIColor.Blue;
Control.ReloadData();
}

}
}
}


CollectionViewSource.cs

using System;
using System.Collections.Generic;
using System.Text;
using Foundation;
using UIKit;
using System.Drawing;
using System.Linq;
using CoreGraphics;
using CustomRenderer_POC;
using Xamarin.Forms;

[assembly: ExportRenderer(typeof(UICollectionViewSource), typeof(CollectionViewSource))]
namespace CustomRenderer_POC
{
class CollectionViewSource : UICollectionViewSource
{
public Array items = null;
public CollectionViewSource(Array elements)
{
items = elements;
}
public override void ItemSelected(UICollectionView collectionView, NSIndexPath indexPath)
{

}

public override UICollectionViewCell GetCell(UICollectionView collectionView, NSIndexPath indexPath)
{
UICollectionViewCell cell = (UICollectionViewCell)collectionView.DequeueReusableCell("MyCell", indexPath);
cell.BackgroundColor = UIColor.Red;
UILabel li = new UILabel(new CGRect(0, 0, 10, 20));
li.Text = "xyz";
cell.AddSubview(li);
return cell;
}
public override nint NumberOfSections(UICollectionView collectionView)
{
return 1;
}
public override nint GetItemsCount(UICollectionView collectionView, nint section)
{
return items.Length;
}
}

}


Now the point is,

I have added a break point at all methods.

But, the methods GetCell and ItemSelected are never gets hit.

Can anyone help...

I followed so many blogs but nothing helps

I bit new to "xamarin" platform

Final output I get is : Output of above program in iOS simulator

Answer

It doesn't produce blue screen as you said. First issue in inheritance from ContentView:

public class CollectionView : ContentView

Do not use ContentView for "empty" views where is main logic in renderers. It's required that Content property set. Or rendering of this control will be skipped. Try to inherit your CollectionView from View class.

Second, I changed your renderer:

    if (Control == null) {
        SetNativeControl (new UICollectionView (new CGRect (0, 0, 300, 256), new UICollectionViewFlowLayout ()));
        Control.RegisterClassForCell(typeof(UICollectionViewCell), "MyCell");
    }

I changed your UICollectionViewLayout to UICollectionViewFlowLayout. According to Apple documentation, it's a abstract base class:

The UICollectionViewLayout class is an abstract base class that you subclass and use to generate layout information for a collection view.

But Apple provides us ready to use implementation - UICollectionViewFlowLayout

Hope this helps