Search code examples
xamarinxamarin.formstelerik

Telerik UI for Xamarin: Property not found for RadListView Binding


I am working on an Android app with Xamarin, using Telerik UI.

The following error is raised when trying to bind a property to a Telerik ListViewTextCell in a RadListView:

[0:] Binding: 'Author' property not found on 'Book', target property: 'Telerik.XamarinForms.DataControls.ListView.ListViewTextCell.Detail'

This happens in even the most minimal cases. Below is an example, drawn largely from the ListView documentation itself.

PageTest.cs:

using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
using Telerik.XamarinForms.DataControls;
using Telerik.XamarinForms.DataControls.ListView;

namespace MyTelerikApp
{
    [DesignTimeVisible(false)]
    public partial class PageTest : ContentPage
    {
        public PageTest()
        {
            InitializeComponent();
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            var listView = new RadListView
            {
                ItemsSource = new ViewModel().Source,
                ItemTemplate = new DataTemplate(() =>
                {
                    var cell = new ListViewTextCell
                    {
                        TextColor = Color.Black,
                        DetailColor = Color.Gray,
                    };

                    cell.SetBinding(ListViewTextCell.TextProperty, new Binding(nameof(Book.Title)));
                    cell.SetBinding(ListViewTextCell.DetailProperty, new Binding(nameof(Book.Author)));

                    return cell;
                }),
                LayoutDefinition = new ListViewLinearLayout { ItemLength = 70 }
            };
            MainPageContent.Children.Add(listView);
        }
    }
}

public class Book
{
    public string Title { get; set; }
    public string Author { get; set; }
}

public class ViewModel
{
    public ViewModel()
    {
        this.Source = new List<Book>{
            new Book{ Title = "The Fault in Our Stars ",  Author = "John Green"},
            new Book{ Title = "Divergent",  Author = "Veronica Roth"},
            new Book{ Title = "Gone Girl",  Author = "Gillian Flynn"},
            new Book{ Title = "Clockwork Angel",  Author = "Cassandra Clare"},
            new Book{ Title = "The Martian",  Author = "Andy Weir"},
            new Book{ Title = "Ready Player One",  Author = "Ernest Cline"},
            new Book{ Title = "The Lost Hero",  Author = "Rick Riordan"},
            new Book{ Title = "All the Light We Cannot See",  Author = "Anthony Doerr"},
            new Book{ Title = "Cinder",  Author = "Marissa Meyer"},
            new Book{ Title = "Me Before You",  Author = "Jojo Moyes"},
            new Book{ Title = "The Night Circus",  Author = "Erin Morgenstern"},
        };
    }

    public List<Book> Source { get; set; }
}

PageText.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:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="GeoGIS.views.PageTest">

    <StackLayout x:Name="MainPageContent">
    </StackLayout>

</ContentPage>

After some searching, it seems that a BindingContext is necessary, but I couldn't get that to work either.


Solution

  • I didn't found BindingContext from your code.And I guess you confused the two usages of ContentPage(XAML and C# ).

    When we created a contentpage,we have two choices(XAML and C#) as follows: enter image description here

    1.When we choose the ContentPage(c#),in this case, there is no xaml.And we can do like this:

    public class TestPage1 : ContentPage
    {
        public TestPage1 ()
        {
            var listView = new RadListView
            {
                BackgroundColor = Color.White,
                ItemsSource = new ViewModel().Source,
                ItemTemplate = new DataTemplate(() =>
                {
                    var cell = new ListViewTextCell
                    {
                        TextColor = Color.Black,
                        DetailColor = Color.Gray,
                    };
    
                    cell.SetBinding(ListViewTextCell.TextProperty, new Binding(nameof(Book.Title)));
                    cell.SetBinding(ListViewTextCell.DetailProperty, new Binding(nameof(Book.Author)));
    
                    return cell;
                }),
                LayoutDefinition = new ListViewLinearLayout { ItemLength = 70 },
            };
    
            Content = new StackLayout {
                Children = {
                    listView
                }
            };
        }
    }
    

    2.When we choose the ContentPage,in this case, code has xaml.We can do like this.

    Put the followinging code in your xaml

    <StackLayout>
        <telerikDataControls:RadListView ItemsSource="{Binding Source}" BackgroundColor="White" x:Name="listView">
            <telerikDataControls:RadListView.BindingContext>
                <local:ViewModel />
            </telerikDataControls:RadListView.BindingContext>
            <telerikDataControls:RadListView.ItemTemplate>
                <DataTemplate>
                    <telerikListView:ListViewTextCell Text="{Binding Title}" Detail="{Binding Author}" TextColor="Black" DetailColor="Gray" />
                </DataTemplate>
            </telerikDataControls:RadListView.ItemTemplate>
            <telerikDataControls:RadListView.LayoutDefinition>
                <telerikListView:ListViewLinearLayout ItemLength="70" />
            </telerikDataControls:RadListView.LayoutDefinition>
        </telerikDataControls:RadListView>
    </StackLayout>
    

    And remove the method OnAppearing() from your code.

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
    
            //BindingContext = new ViewModel();
        }
    
        protected override void OnAppearing()
        {
            base.OnAppearing();
        }
    }
    

    From above code,we can found the BindingContext,it is necessary.

    <telerikDataControls:RadListView.BindingContext>
                <local:ViewModel />
    </telerikDataControls:RadListView.BindingContext>
    

    And we can also BindingContext like this(Any one is ok.):

     BindingContext = new ViewModel();
    

    The result is the same: enter image description here