Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM datagrid binding

I'm using MVVM for my project and I'm trying to bind a table from my database with a DataGrid. But when I run my application datagrid is empty.

MainWindow.xaml.cs:

 public MainWindow(){
        InitializeComponent(); 
        DataContext = new LecturerListViewModel()
    }

MainWindow.xaml:

 <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Source=Lecturers}" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn Header="Surname" Binding="{Binding Surname}"/>
                <DataGridTextColumn Header="Phone" Binding="{Binding Phone_Number}" />
            </DataGrid.Columns>
 </DataGrid>

LecturerListViewModel.cs:

public class LecturerListViewModel : ViewModelBase<LecturerListViewModel> 
{

    public ObservableCollection<Lecturer> Lecturers;
    private readonly DataAccess _dataAccess = new DataAccess();

    public LecturerListViewModel()
    {
        Lecturers = GetAllLecturers();
    }

and ViewModelBase implements INotifyPropertyChanged.

Lecturer.cs

public class Lecturer
{
    public Lecturer(){}

    public int Id_Lecturer { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Phone_Number { get; set; }

What did I do wrong? I checked it with debuger and DataContext contains all lecturers, but ther aren't shown in datagrid.

like image 411
pawel1708hp Avatar asked Nov 08 '12 19:11

pawel1708hp


5 Answers

You have an error in binding. Try this:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Lecturers}" >

Code-behind:

private ObservableCollection<Lecturer> _lecturers = new ObservableCollection<Lecturer>();
public ObservableCollection<Lecturer> Lecturers
{
   get { return _lecturers; }
   set { _lecturers = value; }
}

Here is simple example code (LecturerSimpleBinding.zip).

like image 133
kmatyaszek Avatar answered Nov 20 '22 15:11

kmatyaszek


Here we go

 <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Lecturers}" >

Then

private ObservableCollection<Lecturer> lecturers;

public ObservableCollection<Lecturer> Lecturers
{
    get { return lecturers; }
    set
    {
        lecturers = value;
        this.NotifyPropertyChanged("Lecturers");
    }
}
like image 8
sayed saad Avatar answered Nov 20 '22 17:11

sayed saad


Sayed Saad above is correct. I see two potential problems with your setup, both of which Sayed resolves.

  1. The example posted in the question doen not implement INotifyPropertyChanged
  2. The CLR property being bound to must be a PUBLIC PROPERTY. Fields will not work, as databindindg works via reflection.
like image 6
XamlZealot Avatar answered Nov 20 '22 15:11

XamlZealot


Lecturers is a field, but data binding works with properties only. Try declaring Lecturers like:

public ObservableCollection<Lecturer> Lecturers { get; set; }
like image 2
Joulukuusi Avatar answered Nov 20 '22 17:11

Joulukuusi


MainWindow.xaml.cs: OK

MainWindow.xaml: OK

LecturerListViewModel.cs: OK - assuming that GetAllLecturers() method returns an ObservableCollection of Lecturer.

Lecturer.cs:

public class Lecturer : INotifyPropertyChanged
{
    //public Lecturer(){} <- not necessary

    private int _id;
    public int Id 
    {
        get { return _id; }
        set
        {
            _id = value;
            OnPropertyChanged("Id");
        }
    }
    // continue doing the above property change to all the properties you want your UI to notice their changes.

    ...

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

Check this answer: Adding INotifyPropertyChanged to Model?

like image 1
Eido95 Avatar answered Nov 20 '22 17:11

Eido95