You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中ListView子项绑定自定义列表属性问题求助

Xamarin ListView 绑定问题解决

问题说明

ViewModel 内定义了 ObservableCollection<Player> 类型的 Players 属性,将 ListView 的 ItemsSource 绑定该属性后,在 ItemTemplate 中使用 {Binding Players.Name} 会报错:*"ObservableCollection1类型不存在Name属性"*。但移除 ItemTemplate,将 ItemsSource绑定为{Binding Players[0].Name}` 时,ListView 却能显示所有 Player 的 Name,需要排查问题原因。


相关代码

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>

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;            
}

问题原因与解决方案

核心问题

当 ListView 的 ItemsSource 绑定到 ObservableCollection<Player> 后,ItemTemplate 内部的数据上下文已经自动切换为集合中的单个 Player 对象,此时不需要再通过 Players.Name 来访问属性——Players 是 ViewModel 中的集合属性,单个 Player 对象并没有这个属性,所以会报错。

而使用 {Binding Players[0].Name} 的方式,本质是让 ListView 的所有条目都绑定到 ViewModel 中 Players 集合的第一个元素的 Name 属性,因此所有行都会显示同一个名字,这是错误的用法,并非预期的"显示所有 Player 的 Name"。

修正后的 ListView 代码

将 ItemTemplate 中的绑定改为直接访问 Player 对象的 Name 属性即可:

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

这样 ListView 会自动遍历 Players 集合中的每个 Player 对象,将每个条目的 Label 绑定到对应 Player 的 Name 属性,实现正确的显示效果。


内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:45:01