Jseb
Jseb

Reputation: 1934

MVVM Pattern Listview

I am new to WPF and saw few good videos about MVVM and WPF, however I get confused when I try to show a list of data. For some reason I get no data, in my listview. Here is my class

Model/Person.cs

class Person : INotifyPropertyChanged
    {
        // 1. Fields, Constants
        private int ID;
        private string FirstName;
        private string MiddleName;
        private string LastName;
        private DateTime Birthday;
        private string Prefix;
        private string Email;

        public Person(int ID, string FirstName, string MiddleName, string LastName)
        {
            this.ID= ID;
            this.FirstName = FirstName;
            this.MiddleName = MiddleName;
            this.LastName = LastName;
        }

        /// <summary>
        /// Get or Sets the person first name
        /// </summary>
        public string firstName
        {
            get { return FirstName; }
            set { 
            FirstName = value;
            OnPropertyChanged("FirstName");
            }
        }

        /// <summary>
        /// Get or Sets the person middle name
        /// </summary>
        public string middleName
        {
            get { return MiddleName; }
            set { 
                MiddleName = value;
                OnPropertyChanged("MiddleName");
            }
        }

        /// <summary>
        /// Get or Sets the person last name
        /// </summary>
        public string lastName
        {
            get { return LastName; }
            set { 
            LastName = value;
            OnPropertyChanged("LastName");
            }
        }

        /// <summary>
        /// Get or Sets the person birthday
       /// </summary>
       public DateTime birthday
       {
            get { return Birthday; }
            set { 
                Birthday = value;
                OnPropertyChanged("Birthday");
            }
        }


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

Then I have my View/Person.xaml.cs

public partial class Person : Window
    {
        public Person()
        {
            InitializeComponent();
            lvDataBinding.DataContext = new PersonViewModel();

        }
    }

The xaml is as follow:

<ListView Margin="10" Name="lvDataBinding" ItemsSource="{Binding Person}" Grid.Column="1" Width="auto" Grid.ColumnSpan="8" Grid.Row="1">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding firstName}" Header="First Name" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding lastName}" Header="Last Name" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding middleName}" Header="Middle Name" Width="100"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Birthday}" Header="Birthday" Width="100"/>
                </GridView>
            </ListView.View>

        </ListView>

Last pieces but important here is my ViewModel/PersonViewModel.cs

internal class PersonViewModel
{
    public ObservableCollection<Person> myData { get; set; }

    public PersonViewModel()
    {
        List<Person> myData = new List<Person>();

    }

    public ObservableCollection<Person> getData()
    {
        myData.Add(new Person(12456, "John", "Francis", "Dufour"));
        myData.Add(new Person(12456, "Heather", "Meagan", "Cornthwaite"));
        if (myData.Count > 0)
        {
            return myData;
        }
        else
        {
            return null;
        }

    }
}

I am totally of the chart or is something very small that needs to be fix? Also does it actually follow the MVVM pattern, and in the future I plan to have access to a database, does this pattern work well for me in the future for this.

Upvotes: 1

Views: 218

Answers (1)

Rohit Vats
Rohit Vats

Reputation: 81313

First of all collection name is myData and not Person. So, change ItemsSource to bind to myData property:

<ListView ItemsSource="{Binding myData}">

Also, I would suggest to use ObservableCollection<T> instead of List<T> in case you want your UI to update on add/remove of item in collection because ObservableCollection implement INotifyCollectionChanged which is responsible for notifying UI on any change in collection.

Replace

public List<Person> myData {get; set;}

with

public ObservableCollection<Person> myData {get; set;}

Second, you can only bind with properties and not fields. So change all fields in Person class to properties and make them public.

public int ID {get; set;} // Same for other properties.

Since you are implementing INotifyPropertyChanged, make sure you raise the event properly from all property setters. So, ideal property should look like:

private int id;
public int ID
{
   get
   {
      return id;
   }
   set
   {
      if(id != value)
      {
         id = value;
         OnPropertyChanged("ID");
      }
   }
}

Third, binding path property is case sensitive. Make sure you spell the binding correctly:

It should be FirstName instead of firstName.

<GridViewColumn DisplayMemberBinding="{Binding FirstName}"
                Header="First Name" Width="100"/> // Same for other columns.

Fourth, you never filled the objects in the collection. Method getData() is never called. Fill the collection in constructor itself.

public ObservableCollection<Person> myData {get; set;}

public PersonViewModel()
{
   myData = new ObservableCollection<Person>();
   myData.Add(new Person(12456, "John", "Francis", "Dufour"));
   myData.Add(new Person(12456, "Heather", "Meagan", "Cornthwaite"));
}

Upvotes: 3

Related Questions