Custom Renderers for Telerik Xamarin Forms ListView

12 posts, 0 answers
  1. Supreet
    Supreet avatar
    19 posts
    Member since:
    Mar 2011

    Posted 06 Aug 2015 Link to this post

    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

     

  2. Ves
    Admin
    Ves avatar
    2879 posts

    Posted 07 Aug 2015 Link to this post

    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
  3. DevCraft banner
  4. Rekha
    Rekha avatar
    1 posts
    Member since:
    Oct 2015

    Posted 08 Oct 2015 Link to this post

    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>

     

     

     

     

     

  5. Thorsten
    Thorsten avatar
    5 posts
    Member since:
    Dec 2012

    Posted 28 Jan Link to this post

    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

  6. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 02 Feb Link to this post

    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
  7. Thorsten
    Thorsten avatar
    5 posts
    Member since:
    Dec 2012

    Posted 02 Feb in reply to Pavel R. Pavlov Link to this post

    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

     

  8. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 05 Feb Link to this post

    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
  9. Thorsten
    Thorsten avatar
    5 posts
    Member since:
    Dec 2012

    Posted 05 Feb in reply to Pavel R. Pavlov Link to this post

    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

  10. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 08 Feb Link to this post

    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
  11. Thorsten
    Thorsten avatar
    5 posts
    Member since:
    Dec 2012

    Posted 09 Feb in reply to Pavel R. Pavlov Link to this post

    Hi

     

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

    Regards,

    Thorsten

  12. Arun Kumar
    Arun Kumar avatar
    4 posts
    Member since:
    Dec 2015

    Posted 11 Feb Link to this post

    Hi,

     

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

  13. Pavel R. Pavlov
    Admin
    Pavel R. Pavlov avatar
    1182 posts

    Posted 12 Feb Link to this post

    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
Back to Top
DevCraft banner