EF Code First binding to listbox
I would appreciate it if somebody could tell me how to bind a listbox to the entity framework (EF code first).
I'm using prism and mef. There are two views, one with a button and another with a listbox. (each in their own prism region). By clicking the button I create a new Employee object and insert it to the database via the entity framework.
The problem is that my listbox doesn't show me the newly added Employee object in the list. What should be changed to make this work?
Some parts of the code:
MainView:
<Grid>
<StackPanel>
<TextBlock Text="Hello From MainView (Core Module)" />
<ListBox ItemsSource="{Binding Employees, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FirstName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
&l开发者_Python百科t;/Grid>
MainViewModel:
namespace EmployeeViewer.Core.ViewModels
{
[Export]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class MainViewModel : NotificationObject
{
private IUnitOfWork _UnitOfWork;
[ImportingConstructor]
public MainViewModel(IUnitOfWork unitOfWork) // IEventAggregator eventAggregator
{
this._UnitOfWork = unitOfWork;
Init();
}
private void Init()
{
this.Employees = new ObservableCollection<Employee>(_UnitOfWork.EmployeeRepository.Get());
//this.Employees = new BindingList<Employee>(_UnitOfWork.EmployeeRepository.Get().ToList());
}
public ObservableCollection<Employee> Employees { get; set; }
//public BindingList<Employee> Employees { get; set; }
} }
Get method from GenericRepository:
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>,
IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = _DbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).AsEnumerable();//.ToList();
}
else
{
return query.AsEnumerable();//.ToList();
}
}
Via an ICommand (implemented as RelayCommand) in another region and view, I create and insert a new Employee object to the Entity Framework code first.
public ICommand AddEmployeeCommand
{
get { return _AddEmployeeCommand; }
}
private void AddEmployee()
{
_UnitOfWork.EmployeeRepository.Insert(new Employee() { FirstName = "Test", LastName = "Via cmd" });
_UnitOfWork.Save();
}
After searching on Bing.com I found out that EF has a Local property.
In case you are looking for a solution here is what I did:
I added a new Method to my GenericRepository:
public virtual ObservableCollection<TEntity> GetSyncedEntityItems()
{
return _DbSet.Local;
}
This is the most important part: .Local gives you an ObservableCollection which is in sync with the EF!.
In my ViewModel I do this:
this.Employees = _UnitOfWork.EmployeeRepository.GetSyncedEntityItems();
And adding a new Employee to the EF will cause my other View to update:
private void AddEmployee()
{
_UnitOfWork.EmployeeRepository.Insert(new Employee() { FirstName = "Test", LastName = "Via cmd" });
_UnitOfWork.Save();
}
I don't know if this is the best solution, if there are better options, please do let me know!
You need to fire INotifyPropertyChanged.PropertyChanged, I assume NotificationObject will have a nice way to do that.
When your Employees property goes from null to a list with items, your View needs to be notified so it can update.
Once the Employees property is not null, new items added will automatically update the View (b/c of ObservableCollection).
精彩评论