I have the following ListView that I wish to bind to a custom list in my viewmodel:
<ListView x:Name="listviewPlayers" ItemsSource="{Binding Players}" Height="200">
<ListView.View>
<GridView>
<GridViewColumn Width="235">
<GridViewColumn.Header>
<Label Grid.Column="2" Content ="Name" Foreground="Black" FontSize="10"></Label>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Width="235">
<GridViewColumn.Header>
<Label Grid.Column="1" Content ="Score" Foreground="Black" FontSize="10"></Label>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Width="235">
<GridViewColumn.Header>
<Label Grid.Column="0" Content ="Games" Foreground="Black" FontSize="10"></Label>
</GridViewColumn.Header>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView.ItemTemplate>
<DataTemplate DataType="local:MainPageViewModel">
<Grid Height="25">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="{Binding Name}" FontWeight="Bold" FontSize="10" Foreground="Black">
</Label>
<Label Grid.Column="1" Content="{Binding CurrentScore}" FontSize="10" HorizontalContentAlignment="Center" Foreground="Black">
</Label>
<Label Grid.Column="2" Content="{Binding GamesWon}" HorizontalContentAlignment="Center" FontSize="10" Foreground="Black">
</Label>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In my viewmodel I have Players:
public ObservableCollection<Player> Players
{
get { return players; }
set
{
players = value;
foreach (Player p in players)
{
PlayerNames.Add(p.Name);
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Players"));
}
}
And a Player looks like this:
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")); }
}
What am I doing wrong with my ListView DataTemplate bindings? I have set this on the MainWindow:
d:DataContext="{d:DesignInstance Type=local:MainPageViewModel}"
At the moment the ListView looks like this:
Any advice would be appreciated.
Thanks,
Mike
You must not set the ItemTemplate
property of the ListView.
Set the GridViewColumns' DisplayMemberBinding
property instead.
<ListView x:Name="listviewPlayers" ItemsSource="{Binding Players}" Height="200">
<ListView.View>
<GridView>
<GridViewColumn Width="235" Header="Name"
DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Width="235" Header="Games"
DisplayMemberBinding="{Binding CurrentScore}"/>
<GridViewColumn Width="235" Header="Score"
DisplayMemberBinding="{Binding GamesWon}"/>
</GridView>
</ListView.View>
</ListView>
If you want to explicitly set the UI elements of the header and the cell content, write the GridViewColumn declarations like this:
<GridViewColumn Width="235">
<GridViewColumn.Header>
<TextBlock Text="Name"/>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>