Victor Peralta
Victor Peralta

Reputation: 11

XAML ListView Binding

I am having some problems with XAML syntax, I can't undestand what I am doing wrong.

I have a simple window with a ListView control, and a simple ViewModel with an ObservableColletion of items.

The DataContext of the Window is set correctly, but my problem is with the ItemsSource property of the ListView, when I debud the app I can see that the ListView has the DataContext right and that the DataContext has a list with Items.

But the property ItemsSource is null, if I set it in code behind it works well.

I have searched for an answer but I can't find one, some post seem to have the same problem but it was always the datacontext.

Here is my code.

XAML

<Window x:Class="XAMLExamples.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:XAMLExamples"
        xmlns:vm="clr-namespace:XAMLExamples.ViewModels"
        mc:Ignorable="d"
        Title="Ejemplos XAML" Height="350" Width="525" Background="#FF38551F" WindowStyle="ToolWindow"
         >
    <Window.DataContext>
        <vm:TractoViewModel/>
    </Window.DataContext>

    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto">
            </RowDefinition>
        </Grid.RowDefinitions>
        <ListView ItemsSource="{Binding Path=listaAreas}" Grid.Column="0" x:Name="ListAreas">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Area" Width="120" DisplayMemberBinding="{Binding Area}"/>
                    <GridViewColumn Header="Contenedores" Width="120" DisplayMemberBinding="{Binding Contenedores}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

C#

namespace XAMLExamples.ViewModels
{
    public class TractoViewModel 
    {
        public ObservableCollection<TractoModel> listaAreas = new ObservableCollection<TractoModel>();
        public TractoViewModel()
        {
            for (int i = 0; i < 10; i++)
            {
                listaAreas.Add(
                    new TractoModel { Area= string.Format("Area {0}",i), Contenedores=i}
                    );
            }
            return;
        }
    }
}
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            // With the following line everything is right
            // this.ListAreas.ItemsSource = new XAMLExamples.ViewModels.TractoViewModel().listaAreas;
            // Without the above line ItemsSource is null, even when the DataContext is right
            var iSource = ListAreas.ItemsSource;
            if (iSource == null) return;

        }
    }

Upvotes: 1

Views: 1100

Answers (1)

Clemens
Clemens

Reputation: 128106

Data binding in WPF works with public properties, not fields.

So you have to change your listaAreas field into a property, e.g. like this:

public class TractoViewModel 
{
    public ObservableCollection<TractoModel> listaAreas { get; private set; }
        = new ObservableCollection<TractoModel>();

    ...
}

According to a widely accepted C# naming convention, the property name should also begin with an uppercase letter:

public ObservableCollection<TractoModel> ListaAreas { get; private set; }

Upvotes: 2

Related Questions