Xamarin Binding ListView children to custom list properties

Mike 1 Reputation point
2024-01-19T11:49:59.3033333+00:00

Hi there, I've got an issue with binding to a listview.

ViewModel:

 public class MainPageViewModel : INotifyPropertyChanged
    {

        public MainPageViewModel()
        {

        }

        private ObservableCollection<Player> players;

        public ObservableCollection<Player> Players
        {
            get { return players; }
            set 
            { 
                players = value;                
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Players")); 
            }
        }

        private List<string> playerNames = new List<string>();
        public List<string> PlayerNames
        {
            get { return playerNames; }
            set
            {
                playerNames = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("PlayerNames"));
            }
        }

        private GameType selectedGame;

        public GameType SelectedGame
        {
            get { return selectedGame; }
            set 
            {
                selectedGame = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedGame"));
            }
        }

        private string gameName;

        public string GameName
        {
            get { return gameName; }
            set
            {
                gameName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("GameName"));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        
    }

Player:

public class Player : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); }
        }

        private string currentScore = "0";

        public string CurrentScore
        {
            get { return currentScore; }
            set { currentScore = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentScore")); }
        }

        private string gamesWon = "0";

        public string GamesWon
        {
            get { return gamesWon; }
            set { gamesWon = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("GamesWon")); }
        }

        //public override string ToString()
        //{
        //    return Name;
        //}


    }

ListView:

<ListView x:Name="listviewPlayers" HorizontalOptions="End" ItemsSource="{Binding Players}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Label Text="{Binding Players.Name}" />

                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

Updating viewmodel:

 public void InitGame(Game game)
        {
            //initialize points and setup first player
            viewModel.Players = game.Players;
            viewModel.SelectedGame = game.SelectedGame;
            viewModel.GameName = game.SelectedGame.Name;
            contentMain.BindingContext = viewModel;            
        }

The above ListView bindings don't work - with error : The property 'Name' was not found in type 'ObservableCollection`1'. But if I remove the ItemTemplate and bind the listview's itemssource to {Binding Players[0].Name} the listview displays every name in the List<Player> Players.
I can't see what I'm doing incorrectly. Would appreciate some help here.

Thanks, Mike

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Anonymous
    2024-01-22T01:55:18.6466667+00:00

    Hello, If you add the Label to the Listview's DataTemplate, you need to add the <ViewCell> outside the Label. And please change the Players.Name to the Name directly like the following code.

    <ListView x:Name="listviewPlayers" HorizontalOptions="End" ItemsSource="{Binding Players}">
          <ListView.ItemTemplate>
              <DataTemplate>
                  <ViewCell>
                      <Label Text="{Binding Name}" />
                 </ViewCell>
             </DataTemplate>
          </ListView.ItemTemplate>
    </ListView>
    

    As note, you need to make sure InitGame method will be executed when your application is running.

    By the way, if you have some doubt about the databinding and MVVM, you can refer to this From Data Bindings to MVVM.

    Best Regards, Leon Lu


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.