ListVIew Data Bindings

235 Views Asked by At

Im trying to display info about a list of cars. The list is stored in CarLibrary, and I can't get the information to display underneath the respective headers.

Here is my xaml:

        <TabItem Header="Overview">
            <Grid>
                <ListView Margin="10" ItemsSource="{Binding CarLibrary}">
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Header="Picture" Width="100" DisplayMemberBinding="{Binding PicturePath}"/>
                            <GridViewColumn Header="Year" Width="100" DisplayMemberBinding="{Binding Year}"/>
                            <GridViewColumn Header="Make" Width="100" DisplayMemberBinding="{Binding Make}"/>
                            <GridViewColumn Header="Model" Width="100" DisplayMemberBinding="{Binding Model}"/>
                        </GridView>
                    </ListView.View>
                </ListView>
            </Grid>

        </TabItem>

And here is the relevant code from the view model in c#, each Car object has the properties of Make, Model, Year, and PicturePath:

namespace CarApp
{
public class Carvm : INotifyPropertyChanged
{
    private CarLib carLibrary;
    public CarLib CarLibrary
    {
        get { return carLibrary; }
        set
        { 
            carLibrary = value;
            NotifyPropertyChanged("CarLibrary");
        }
    }

    public Carvm()
    {
        carLibrary = new CarLib();
        newCar = new Car();
        currentCar = new Car();
        rmCommand = new DeleteCommand(carLibrary);
        touchCommand = new AddCommand(carLibrary, newCar);

        //load list from disk on startup
        carLibrary.ReadList();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}
}

Here is CarLib:

namespace CarApp
{
public class CarLib : INotifyPropertyChanged
{
    private ObservableCollection<Car> list;

    public ObservableCollection<Car> List 
    {
        get { return list; }
        set {
            list = value;
            NotifyPropertyChanged("List");
        }
    }

    public CarLib()
    {
        List = new ObservableCollection<Car>();
    }

    /// <summary>
    /// Deserializes list of cars and returns the list to user
    /// </summary>
    public void ReadList()
    {
        //create local list to hold data
        ObservableCollection<Car> carList = new ObservableCollection<Car>();

        try
        {
            using (Stream stream = File.Open("data.bin", FileMode.OpenOrCreate))
            {
                BinaryFormatter bin = new BinaryFormatter();


                try
                {
                    //point List to deserialized stream
                    List = (ObservableCollection<Car>)bin.Deserialize(stream);
                }
                catch (SerializationException)
                {
                    Console.WriteLine("The list is empty.");
                }

            }
        }

        catch (SerializationException e)
        {
            if (e.Source != null)
            {
                Console.WriteLine("Empty List");
            }
        }
    }

    /// <summary>
    /// Serialize list supplied by the user and write to disk
    /// </summary>
    public void WriteList()
    {
        try
        {
            using (Stream stream = File.Open("data.bin", FileMode.Create))
            {
                BinaryFormatter bin = new BinaryFormatter();

                //write list to disk
                bin.Serialize(stream, List);
            }
        }
        catch (IOException)
        {
            Console.WriteLine("Empty List");
        }

    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}
}
2

There are 2 best solutions below

0
On

It would be nic to have CarLibrary defined as an ObservableCollection of Car:

public ObservableCollection<Car> CarLibrary {get; set;}

Then load the collection in the constructor using CarLib.ReadList() method. Assumming that ReadList returns IEnumerable<Car> you can then convert it to ObservableCollection using ToObservalbe extension method:

CarLibrary = new CarLib().ReadList().ToObservable();

Your XAML view looks good to me and that should render your list of cars.

0
On

The issue was that in the ListView I set the ItemsSource="{Binding CarLibrary}" when it should have been: ItemsSource="{Binding CarLibrary.List}". Thank you all for your help.