8

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.

kmatyaszek
  • 19,016
  • 9
  • 60
  • 65
pawel1708hp
  • 759
  • 2
  • 6
  • 12

5 Answers5

10

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).

kmatyaszek
  • 19,016
  • 9
  • 60
  • 65
  • Still not working. But now there are only headers in datagrid, with my solution I had at least empty rows – pawel1708hp Nov 08 '12 at 20:04
  • Thank you so much, it works. Here was the problem: //public ObservableCollection Lecturers; private ObservableCollection _lecturers = new ObservableCollection(); public ObservableCollection Lecturers { get { return _lecturers; } set { _lecturers = value; } } – pawel1708hp Nov 08 '12 at 20:18
  • ohh.. yeah, I focused on binding errors and I forgot how you create this ObservableCollection. – kmatyaszek Nov 08 '12 at 20:21
  • @kmatyaszek Thanks for the sample you provided +1 for that, If I want to bind click events from the form to my VIEWMODEL, How can I do that in a way that the selectedIndex/ select row id is provided to my viewmodel – Arijit Mukherjee Jun 16 '14 at 07:14
  • @ArijitMukherjee you can create in vm property `SelectedLecturer` (type of `Lecturer`) and binding to `DataGrid.SelectedItem`: ``, this solution should solve your problem. – kmatyaszek Jun 16 '14 at 20:10
8

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");
    }
}
sayed saad
  • 672
  • 7
  • 12
6

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.
XamlZealot
  • 693
  • 5
  • 12
2

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

public ObservableCollection<Lecturer> Lecturers { get; set; }
skink
  • 5,133
  • 6
  • 37
  • 58
1

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?

Community
  • 1
  • 1
Eido95
  • 1,313
  • 1
  • 15
  • 29