Reputation: 287
I feel like what I am trying to do is pretty simple and straightforward, but from the research I have done, it looks like I am doing things right. I just made a vanilla WPF project, setup entity framework and now I am trying to bind my employees collection (which has data) to a data grid.
XAML:
<DataGrid Name="EmployeesView" CanUserAddRows="False" CanUserResizeColumns="True" CanUserSortColumns="True" IsReadOnly="True" Margin="10,10,0,0">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" />
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" />
<DataGridTextColumn Header="Phone Number" Binding="{Binding PhoneNumber}" />
<DataGridTextColumn Header="Pay Rate" Binding="{Binding PayPerHour}" />
<DataGridTextColumn Header="Hire Date" Binding="{Binding HireDate}" />
</DataGrid.Columns>
</DataGrid>
Here's my model:
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public double PayPerHour { get; set; }
public DateTime HireDate { get; set; }
}
And here my code behind (not using MVVM)
private CompanyContext db = new CompanyContext();
public ObservableCollection<Employee> Employees = new ObservableCollection<Employee>();
public AddEmployee()
{
RefreshGrid();
InitializeComponent();
}
private void RefreshGrid()
{
Employees = db.Employees.ToObservableCollection();
EmployeesView = new DataGrid();
EmployeesView.ItemsSource = Employees;
}
.ToObservableCollection
is an extension method that just casts ienumerable to ObservableCollection
I have also tried this with List<>
. For some reason I have to call EmployeesView = new DataGrid();
other wise EmployeesView.ItemsSource = Employees;
gives a null ref on EmployeesView
. That may be where I am going wrong? I'm at a lose here, any ideas?
Upvotes: 0
Views: 677
Reputation: 2620
Here is a simple example:
<Window x:Class="DatagridBInding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid ItemsSource="{Binding Items}"/>
</Grid>
Codebehind:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ObservableCollection<DataTableItem> _Items;
public ObservableCollection<DataTableItem> Items
{
get { return _Items; }
set
{
_Items = value;
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items = new ObservableCollection<DataTableItem>();
Task.Factory.StartNew(() =>
{
Dispatcher.Invoke(() =>
{
for (int i = 0; i < 10; i++)
Items.Add(new DataTableItem() { Data = "Data " + i });
}
);
});
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
And the item class:
public class DataTableItem : INotifyPropertyChanged
{
private string _Data;
public string Data
{
get { return _Data; }
set
{
_Data = value;
PropertyChanged(this, new PropertyChangedEventArgs("Data"));
}
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
As far as i see you haven't defined your Employees as a public property. Watch my example and do so.
Regarding the Employee, check my DataTableItem and the implementation of the INotifyPropertyChanged.
You also have a way of adding items from another thread, just in case you need this scenario when loading your items from the database.
One more thing, do not refresh the grid like that, but try the way i did in my above example :
Items = new ObservableCollection<DataTableItem>();
or
Items.Clear();
and then add your items, async or not, this is upon you.
Upvotes: 1