1
votes

I am trying to create a contentview which has a listview xamarinforms. I want to set a property of the contentview that is then used to bind the data to the listview.

Unfortunately I am not able to populate it. I broke down the example to get a poc. The desired result should be a contentpage with all the names. Any helb appreciated. Thx in advance!

The example consists of: Contentpage: Adds the contentview. It also has a bindingcontext to a viewmodel - CompanyVM. Sets Property PersonList of contentview to PersonVM.Personlist. (Unsure if correct)

Contentview.XAML: XAML of contentview Bindings for listview (unsure if correct)

Contentview.cs XAML code-behind Property Settings for contentview

CompanyVM: Viewmodel used

Company & Person & Mockup Simple classed to work with

Example

ContentMainPage

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:cv="clr-namespace:ContentViewExample.XAML"
             xmlns:vm="clr-namespace:ContentViewExample.ViewModel"
             xmlns:local="clr-namespace:ContentViewExample"
             x:Class="ContentViewExample.MainPage"
             x:Name="mainpage">

    <ContentPage.BindingContext>
        <vm:CompanyVM/>
    </ContentPage.BindingContext>

    <StackLayout>
        <cv:personlistCV Company="{x:Reference mainpage }"/>
        <!--Is this correct?-->
    </StackLayout>

</ContentPage>

```

Contentview.XAML

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ContentViewExample.XAML.personlistCV"
             x:Name="cvPersons">
  <ContentView.Content>
      <StackLayout>
            <ListView x:Name="lstPerson"
                  ItemsSource="{Binding Company.Persons}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal">
                                <Label  Text="{Binding Path=Name}"/>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

        </StackLayout>
  </ContentView.Content>
</ContentView>

Contentview.cs

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace ContentViewExample.XAML
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class personlistCV : ContentView
    {
        public personlistCV ()
        {
            InitializeComponent ();
        }

        //CompanyProperty
        public static readonly BindableProperty CompanyProperty =
            BindableProperty.Create(
                "Company",
                typeof(CompanyVM),
                typeof(personlistCV),
                null);

        public personlistCV Company
        {
            set { SetValue(CompanyProperty, value); }
            get { return (personlistCV)GetValue(CompanyProperty); }
        }
    }
}

CompanyVM

namespace ContentViewExample.ViewModel
{
    public class CompanyVM: ViewModelBase
    {
        ObservableCollection<Person> persons;
        string companyname;

        public CompanyVM()
        {
            companyname = "Test Company";
            persons = new ObservableCollection<Person>();

            foreach (Person item in MockData.GetPeople())
                persons.Add(item);
        }

        public string Company
        {
            set { SetProperty(ref companyname, value); }
            get { return companyname; }
        }


        public ObservableCollection<Person> Persons
        {
            set { SetProperty(ref persons, value); }
            get { return persons; }
        }
    }
}

Company & Person

public class Company
{
    public string Name { get; set; }
}
public class Person
{
    public string Name{get;set;}
}

public static class MockData
{
    public static List<Person> GetPeople()
    {
        List<Person> tmp = new List<Person>
        {
            new Person
            {
                Name="Ted"
            },
            new Person
            {
                Name="Jennifer"
            },
            new Person
            {
                Name="Andy"
            },

            new Person
            {
                Name="Oscar"
            }
        };

        return tmp;
    }
}
1
Try to Make ItemsSource="{Binding Company.Persons}"> to ItemsSource="{Binding Persons}"> this in Contentview.XAMLR15
hi @Arvindraja - Thank you for the hint.jan.michael

1 Answers

1
votes

You have tried to bind personlistCV.Company the following way

<StackLayout>
    <cv:personlistCV Company="{x:Reference mainpage }"/>
    <!--Is this correct?-->
</StackLayout>

I see several issues here:

  • Bindings are set with the XAML extension Binding
  • The Company is set to the mainpage, which is of Type MainPage.
    • It should rather be set to mainpage.BindingContext (this is a CompanyCV object)

Furthermore the personlistCV.Company is of type personlistCV, which does not really make sense. The field should be of type CompanyVM, since we'd like to bind the viewmodel (and personlistCV does not even have a Persons (bindable) property).

Having said that, the following code should work:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:cv="clr-namespace:ContentViewExample.XAML"
             xmlns:vm="clr-namespace:ContentViewExample.ViewModel"
             xmlns:local="clr-namespace:ContentViewExample"
             x:Class="ContentViewExample.MainPage"
             x:Name="mainpage">

    <ContentPage.BindingContext>
        <vm:CompanyVM/>
    </ContentPage.BindingContext>

    <StackLayout>
        <cv:personlistCV Company="{Binding Path=BindingContext, Source={x:Reference mainpage}}"/> <!-- Bind the element to `mainpage.BindingContext` --> 
    </StackLayout>
</ContentPage>

Maybe

<cv:personlistCV Company="{Binding .}"/>

could work, too, since . usually binds to the BindingContext of the view and the BindingContext of the page is passed down to the views (unless another BindingContext is set for the views explicitly).

And for the companyCV

public partial class personlistCV : ContentView
{
    public personlistCV ()
    {
        InitializeComponent ();
    }

    //CompanyProperty
    public static readonly BindableProperty CompanyProperty =
        BindableProperty.Create(
            "Company",
            typeof(CompanyVM),
            typeof(personlistCV),
            null);

    public CompanyVM Company
    {
        set { SetValue(CompanyProperty, value); }
        get { return (personlistCV)GetValue(CompanyProperty); }
    }
}