xamarinxamarin.formsdata-bindingitemsource

Populating listview from a list


With the inspiration of an example, "Listing Colors with BoxView" given in Xamarin documenation https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/boxview , I've been trying to populate my listview in the same way. However nothing would show up.

In my class PostList which creates an object looks something like this:

public String Body { get; set; }
public String Subject { get; set; }
public Coordinate Position { get; set; }

private List<Post> all = new List<Post>();

public PostList(List<Post> list)
{
       
        all = list;
        method();
}

public void method()
{
        List<PostList> All = new List<PostList>();
       
       foreach(Post x in all)
       {
          PostList Pl = new PostList
          {
                
                Subject = x.getSubject(),
                Body = x.getBody(),
                Position = x.getCoordinate()
          };
          All.Add(Pl);
      }
}
public static IList<PostList> All { set; get; }

And the XAML class for displaying is given below:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:local="clr-namespace:EE.Model"
         x:Class="EE.View.CWT"
         NavigationPage.HasNavigationBar="False"
         NavigationPage.BackButtonTitle="False"
         ControlTemplate="{StaticResource Template}">

    <ListView SeparatorVisibility="Default"
          ItemsSource="{x:Static local:PostList.All}">
    

    <ListView.RowHeight>
        <OnPlatform x:TypeArguments="x:Int32">
            <On Platform="iOS, Android" Value="180" />
        </OnPlatform>
    </ListView.RowHeight>
    <ListView.WidthRequest Value="20"/>

    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ContentView Margin="5,5,5,5">
                    <Frame OutlineColor="LightGray">
                        <StackLayout>
                            <StackLayout Orientation="Horizontal">
                                <StackLayout x:Name="SL" Padding="0">
                                    <Label x:Name="Title" Text="{Binding Subject}"/>
                                </StackLayout>
                            </StackLayout>
                         </StackLayout>
                    </Frame>
                </ContentView>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>

I have checked that the list "All" is populated, but I can't figure out what should be done for it to display.


Solution

  • There are two All in your codes above.

    One is

    public static IList<PostList> All { set; get; },

    another is in your method()

    List<PostList> All = new List<PostList>();

    Try to change it to keep them consistent:

    public void method()
    {
       All = new List<PostList>();
       
       foreach(Post x in all)
       {
          PostList Pl = new PostList
          {
                
                Subject = x.getSubject(),
                Body = x.getBody(),
                Position = x.getCoordinate()
          };
          All.Add(Pl);
      }
    }
    

    I'm also confused about how you instantiate your ViewModel.where do you pass the parameter with this public PostList(List<Post> list) constructor ?

    we usually do like this :

    <ListView SeparatorVisibility="Default"
          x:Name ="listview">
        ...
    
    </ListView>
    

    in code behind:

    public YourPage()
      {
          InitializeComponent();
          PostList list = new PostList(your List<Postlist>);
          listview.ItemsSource = list.All;
      }
    

    viewmodel:

    public class PostList
    {
    
      public String Body { get; set; }
      public String Subject { get; set; }
      public Coordinate Position { get; set; }
      private List<Post> all = new List<Post>();
      public PostList(List<Post> list)
      {
       
        all = list;
        method();
      }
    
      public void method()
      {
        All = new List<PostList>();
       
        foreach(Post x in all)
        {
          PostList Pl = new PostList
          {
                
                Subject = x.getSubject(),
                Body = x.getBody(),
                Position = x.getCoordinate()
          };
          All.Add(Pl);
        }  
      }
      public IList<PostList> All { set; get; }
    }
    

    or use the x:Static resource:

    public class PostList
    {
    
      public String Body { get; set; }
      public String Subject { get; set; }
      public Coordinate Position { get; set; }
      private static List<Post> all = new List<Post>();
      static PostList()
      {
    
        all = xxx;//here create a List<Post>
        method();
      }
    
      public static void method()
      {
        All = new List<PostList>();
    
        foreach(Post x in all)
        {
          PostList Pl = new PostList
          {
    
            Subject = x.getSubject(),
            Body = x.getBody(),
            Position = x.getCoordinate()
          };
          All.Add(Pl);
        }  
       }
      public IList<PostList> All { set; get; }
    }
    

    then you could binding in your xaml like:

    <ListView SeparatorVisibility="Default"
          ItemsSource="{x:Static local:PostList.All}">
      ...
    </ListView>