This is a migrated thread and some comments may be shown as answers.

Custom Renderers for Telerik Xamarin Forms ListView

13 Answers 611 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Supreet
Top achievements
Rank 1
Supreet asked on 06 Aug 2015, 09:11 AM

Hello Team, 

I am pretty exited to see the new telerik control from you. This was long anticipated. 

However, I was a little disappointed to see that the Forms edition of the ListView does not have Drag & Drop reorder support. 

I understand X.Forms is also in its infancy & its difficult to come up with features that support all 3 platforms in the same way.

 

At the same time, I was also very happy to see that ListView for Xamarin Android & iOS do support Drag & Drop for reorder. 

My question is, is there a way I can write a Custom ListView Renderer of sort on xamarin Forms, that will then allow me to convert the Telerik Forms ListView to Telerik iOS or Android List view so I can support drag & drop of items? 

Is there a way we can do it? Can you share any examples or at least guide us in right direction? 

 

Thanks 

ST

 

13 Answers, 1 is accepted

Sort by
0
Ves
Telerik team
answered on 07 Aug 2015, 08:45 AM
Hi Supreet,

Here is how to create custom renderers for RadListView. Let's start with iOS:

 - Create a class, which inherits from Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer
 - Override OnElementChanged method. In this method, after calling the base method, this.Control will hold a reference to the native control, so you can set its AllowCellReorder to true.

public class MyListViewRenderer : Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer
    {
        protected override void OnElementChanged(Xamarin.Forms.Platform.iOS.ElementChangedEventArgs<Telerik.XamarinForms.DataControls.RadListView> e)
        {
            base.OnElementChanged(e);
            // e.NewElement is Telerik.XamarinForms.DataControls.RadListView
            // e.Control is Telerik.XamarinForms.DataControlsRenderer.iOS.TKExtendedListView, which inherits TelerikUI.TKListView i.e. this is the native control
            (this.Control as TelerikUI.TKListView).AllowsCellReorder = true;
        }
    }

- Do not forget to register the renderer:
[assembly:ExportRenderer(typeof(Telerik.XamarinForms.DataControls.RadListView), typeof(App12.iOS.MyListViewRenderer))]


For Android, the process is quite similar:

- Create a class which inherits from Telerik.XamarinForms.DataControlsRenderer.Android.ListViewRenderer

​-
Override OnElementChanged method. In this method, after calling the base method, this.Control will hold a reference to a wrapper, that in turn holds the native control. In Android, you need to add ItemReorderBehavior:

public class MyListViewRenderer : Telerik.XamarinForms.DataControlsRenderer.Android.ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Telerik.XamarinForms.DataControls.RadListView> e)
        {
            base.OnElementChanged(e);
            // this.Control holds a reference to Telerik.XamarinForms.DataControlsRenderer.Android.ListView.RadListViewWrapper, which in turn holds
            // the native com.Telerik.Widget.List.RadListView
            (this.Control as RadListViewWrapper).ListView.AddBehavior(new ItemReorderBehavior());
        }
    }

 - Finally, register the renderer:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.DataControls.RadListView), typeof(App12.Droid.MyListViewRenderer))]


Best regards,
Ves
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Rekha
Top achievements
Rank 1
answered on 08 Oct 2015, 06:25 PM

This example was very useful. I created a DragableListView that extended RadListView

using System;
using Telerik.XamarinForms.DataControls;

namespace SDKBrowser
{
    public class DraggableListView :RadListView
    {

    }
}

Then I modified FirstLook.xaml to use the above: and voila list view reordering works beautifully!!

Keep up the good work Telerik !!

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SDKBrowser.Examples.ListView.FirstLook"
             xmlns:telerikDataControls="clr-namespace:SDKBrowser;assembly=SDKBrowser"
             xmlns:telerikListView="clr-namespace:SDKBrowser.DraggableListView;assembly=SDKBrowser">
  <Grid>
    <telerikDataControls:DraggableListView ItemsSource="{Binding Items}"/>
  </Grid>
</ContentPage>

 

 

 

 

 

0
Thorsten
Top achievements
Rank 1
answered on 28 Jan 2016, 11:13 PM

Hi

Is there a working sample? I tried to implemented it as mentioned in the previous posts.

On iOS I see the handles and can move the rows, but as soon as I drop them, I get an ThrowKeyNotFoundException.

Not sure what I'm missing.

On android I guess I will need another layout - the current one does not show anything.

 

Thanks, 

Thorsten

0
Pavel R. Pavlov
Telerik team
answered on 02 Feb 2016, 08:03 AM
Hello Thorsten,

Item reordering is builtin feature of the RadListView component. You can enable it by setting the IsItemsReorderEnabled property to True.

Regards,
Pavel R. Pavlov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Thorsten
Top achievements
Rank 1
answered on 03 Feb 2016, 12:10 AM

Hello Pavel,

 

thank you for your reply. 

This led me to test the issue in a separate project without other additional components.

Step one was as simple as possible. Just a Xamarin forms project with this XAML page.

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:test="clr-namespace:ReorderTest.Controls;assembly=ReorderTest"
             x:Class="ReorderTest.MainPage">
<test:DraggableListView x:Name="LV"/>
 
</ContentPage>

 

This was working without issues on iOS and Android.

 

I then tried to use a view Model and bind it to the XAML.

<test:DraggableListView x:Name="LV" ItemsSource="{Binding List}" />

 

Result: Working without problems on Android, but throwing the exception on iOS when doing the reorder.

"The given key was not present in the dictionary." 

Here is the full stack trace:

  at System.ThrowHelper.ThrowKeyNotFoundException () [0x00000] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/throwhelper.cs:70 
  at System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (System.Collections.Generic.TKey key) [0x00021] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/collections/generic/dictionary.cs:176 
  at Telerik.XamarinForms.Common.XamarinToNativeControlExtensions.UpdateCollection[T,K] (Telerik.XamarinForms.Common.T nativeElement, Telerik.XamarinForms.Common.K xfЕlement, System.String propertyName, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) [0x00024] in <filename unknown>:0 
  at Telerik.XamarinForms.DataControlsRenderer.iOS.ListViewRenderer.ItemsSourceCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000c] in <filename unknown>:0 
  at Telerik.XamarinForms.DataControls.RadListView.RaiseItemsSourceCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000a] in <filename unknown>:0 
  at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00012] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:286 
  at System.Collections.ObjectModel.ObservableCollection`1[T].OnCollectionChanged (NotifyCollectionChangedAction action, System.Object item, Int32 index) [0x00000] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:349 
  at System.Collections.ObjectModel.ObservableCollection`1[T].RemoveItem (Int32 index) [0x0002b] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/System/compmod/system/collections/objectmodel/observablecollection.cs:203 
  at System.Collections.ObjectModel.Collection`1[T].Remove (System.Collections.ObjectModel.T item) [0x0002d] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/collections/objectmodel/collection.cs:134 
  at System.Collections.ObjectModel.Collection`1[T].System.Collections.IList.Remove (System.Object value) [0x00022] in /Users/builder/data/lanes/2689/962a0506/source/maccore/_build/Library/Frameworks/Xamarin.iOS.framework/Versions/git/src/mono/external/referencesource/mscorlib/system/collections/objectmodel/collection.cs:350 
  at Telerik.XamarinForms.DataControlsRenderer.iOS.ListView.ListViewDelegate.DidReorderItemFromIndexPath (TelerikUI.TKListView listView, Foundation.NSIndexPath originalIndexPath, Foundation.NSIndexPath targetIndexPath) [0x00044] in <filename unknown>:0 
  at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/2689/962a0506/source/maccore/src/UIKit/UIApplication.cs:77 
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/2689/962a0506/source/maccore/src/UIKit/UIApplication.cs:61 
    at ReorderTest.iOS.Application.Main (System.String[] args) [0x00008] in /Users/XXX/ReorderTest/ReorderTest/ReorderTest.iOS/Main.cs:17 

 

Regards,

Thorsten

 

0
Pavel R. Pavlov
Telerik team
answered on 05 Feb 2016, 07:30 AM
Hi Thorsten,

The reported issue is already fixed in our latest official version. Please download the new binaries and give it a try one more time.

Do not hesitate to contact us again if you need any further assistance.

Regards,
Pavel R. Pavlov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Thorsten
Top achievements
Rank 1
answered on 05 Feb 2016, 05:12 PM

Hi Pavel

 

I'm using version 2016.1.113 (January 13th, 2016)

As far as I can see, this is the most recent version, but the error occurs on iOS.

Kind regards,

Thorsten

0
Pavel R. Pavlov
Telerik team
answered on 08 Feb 2016, 07:19 AM
Hello Thorsten,

Last Thursday we released an update. The latest version is 2016.1.0204. Please check it out and let us know how it goes. 

Regards,
Pavel R. Pavlov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Thorsten
Top achievements
Rank 1
answered on 09 Feb 2016, 12:48 PM

Hi

 

Unfortunately it is not working. I opened a support ticket with a sample.

Regards,

Thorsten

0
Arun Kumar
Top achievements
Rank 1
answered on 11 Feb 2016, 08:00 AM

Hi,

 

From IOS Renderer how to get the reordered items. Any Event or listener which get triggered when the Reorder completes?

0
Pavel R. Pavlov
Telerik team
answered on 12 Feb 2016, 10:09 AM
Hi arun,

The current version of the reorder API does not expose such event. This is why you cannot be notified when end users finish reordering out of the box. There is a way to achieve your requirement but it is related with creating custom renderer (one per platform, total two) and custom behavior or overriding specific methods. Here is what you can try to implement.

For Android project:
You will need to create a custom renderer. This is a class deriving from ListViewRenderer. In that class you can override the CreateReorderBehavior() method. In that method you should return another custom class. The second custom class should derive from ItemReorderBehavior. Inside it you will be able to override the EndReorder() method. This method will notify you when item has been reordered.

For iOS project:
You will also need to create a custom renderer (class deriving from ListViewRenderer). In that renderer you will be able to override the CreateListViewDelegateOverride() method. Inside that method you will need to return another custom class deriving from ListViewDelegate. In that customized class you will be able to override the DidReorderItemFromIndexPath() method.


I hope this will get you started.

Regards,
Pavel R. Pavlov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Chandan
Top achievements
Rank 1
answered on 31 Aug 2017, 05:53 AM
Can I create custom renderer like this for every control in telerik ui for Xamarin forms??

What I want is, the UI must be exactly same on each platform, thus custom renderering has to be done for each control. so will telerik be useful? Please reply.

Thankyou in advance.

If yes, can you please share some links from where I can get some content to read.

0
Stefan Nenchev
Telerik team
answered on 04 Sep 2017, 08:32 AM
Hi Chandan,

You can create custom renderers for all controls within the Telerik UI for Xamarin Suite in order to access the native control and platform specific APIs. However, we cannot guarantee that identical look can be achieved due to the platforms' specifications. If you need to work with the native controls, I suggest you review the Native Controls Wrappers section. It provides information for the native controls in iOS and Android and the approach for creating renderers is identical to the one my colleague has provided in the first answer.

Have a great week.

Regards,
Stefan Nenchev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
ListView
Asked by
Supreet
Top achievements
Rank 1
Answers by
Ves
Telerik team
Rekha
Top achievements
Rank 1
Thorsten
Top achievements
Rank 1
Pavel R. Pavlov
Telerik team
Arun Kumar
Top achievements
Rank 1
Chandan
Top achievements
Rank 1
Stefan Nenchev
Telerik team
Share this question
or