= Entity Framework and Windows Presentation Foundation Walk Through = == Entity Framework == The first thing to do is get the Database Model going: 1. Fire up Visual Studio 2012 1. Create a new project called EF_WPF_Example, Select Windows, WPF project type. 1. If the Data Sources side bar (windows) is not visible Press Shift+Alt+D 1. Click Add New Data Sources and in the wizard... a. Click Database, Next a. Entity Data Model, Next a. Generate from database, Next a. Click New Connection... a. Give your server name and click on the drop down under "Select or enter a database name" a. Select the University Database Example that we have been working on. a. Test the connection to make sure that it works, then click OK a. Make a special note of the connection string name, Click next a. Under tables place check marks next to "advisor", "instructor", "student" and notice the Model Namespace (Mine was UniversityExampleModel), Click Finish. Your file should now look like this: {{attachment:EFModel.png}} One last thing: Rename the file to be UniversityModel (I just don't like Model1.edmx). ---- == WPF View Part (1) == Now we will build the GUI (You could do this in Blend too, but I'm going to use Visual Studio 2012). 1. Make sure the toolbox is visible. 1. Add two Label and two TextBox objects on the screen, one DataGrid and three buttons so that it looks like the following ('''Don't worry about the Binding yet though!'''): {{attachment:XAML_View.png}} ---- == Creating the View Model (MVVM) == There are two parts to the view model. First you need to create a class that implements ICommand. I'm using a rather standard way of doing this called a DelegateCommand. This paradigm allows you to use the same ICommand object over and over again without having to write custom code into each one. The primary methods are there and we do some house keeping based on those methods. I'll be happy to explain how this works if you don't understand (or you can watch the video). {{{#!csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; namespace EF_WPF_Example { class DelegateCommand : ICommand { private readonly Predicate _canExecute; private readonly Action _execute; private bool flagExecutable = false; public event EventHandler CanExecuteChanged; public DelegateCommand(Action execute, Predicate canExecute) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { bool flag = _canExecute == null || _canExecute(parameter); if (flagExecutable != flag) { flagExecutable = !flagExecutable; RaiseCanExecuteChanged(); } return flag; } public void Execute(object parameter) { _execute(parameter); } public void RaiseCanExecuteChanged() { if (CanExecuteChanged != null) { CanExecuteChanged(this, EventArgs.Empty); } } } } }}} The second part is the actual View model itself: {{{#!csharp using System.Collections.Generic; using System.ComponentModel; using System.Linq; using EF_WPF_Example.Annotations; namespace EF_WPF_Example { class MainViewModel : INotifyPropertyChanged { private readonly UniversityExampleEntities _context = new UniversityExampleEntities(); private readonly List _students; private readonly DelegateCommand _prev; private readonly DelegateCommand _next; private readonly DelegateCommand _save; private int _index; private readonly int _maxIndex; public string Name { get { return _students[_index].name; } set { _students[_index].name = value; OnPropertyChanged("Name"); } } public string Department { get { return _students[_index].dept_name; } set { _students[_index].dept_name = value; OnPropertyChanged("Department"); } } public List Classes { get { return _students[_index].takes.ToList(); } } public DelegateCommand Prev { get { return _prev; } } public DelegateCommand Next { get { return _next; } } public DelegateCommand Save { get { return _save; } } public MainViewModel() { _students = _context.students.Include("takes").ToList(); _index = 0; _maxIndex = _students.Count() - 1; _next = new DelegateCommand(MoveNext, x=>_index < _maxIndex); _prev = new DelegateCommand(MovePrev, x=>_index > 0); _save = new DelegateCommand(x=>_context.SaveChanges(), x=>true); } private void MoveNext(object o) { _index++; NotifyAll(); Prev.CanExecute(null); Next.CanExecute(null); } private void MovePrev(object o) { _index--; NotifyAll(); Prev.CanExecute(null); Next.CanExecute(null); } private void NotifyAll() { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Name")); PropertyChanged(this, new PropertyChangedEventArgs("Department")); PropertyChanged(this, new PropertyChangedEventArgs("Classes")); PropertyChanged(this, new PropertyChangedEventArgs("Next")); PropertyChanged(this, new PropertyChangedEventArgs("Prev")); PropertyChanged(this, new PropertyChangedEventArgs("Save")); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged(string property) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(property)); } } } }}} Now that we have a view model that works (make sure that you have compiled it and that it does compile). We are ready to go back and tie the View to the View Model. ---- == WPF View Part 2 == Below is the completed Xaml code. Pay particular attention to the way in which the xmlns, "my" is added to the xaml. The Window.DataContext defines the View Model that this View will attempt to create when you bring up the view. The different Binding attributes map to properties of the View Model identified. {{{#!xaml