Advantage of this pattern of separation is the functional development provided by MVC as well as using the advantages of XAML by binding data while using it. ViewModel, and any Business Layer’s inherent data checking features to validate any incoming data. The result is that the Model and Foundation drive as much of the operations as possible, minimizing the need for “code behind” especially in the View.
Model: as in the classic MVC / MVP pattern, the model refers to either an object model that represents the real state content or the data access layer that represents that content (a data-centric approach).
View: as in the classic MVC / MVP pattern, the view refers to all elements displayed by the GUI such as buttons, windows, graphics, and other controls.
ViewModel: the ViewModel is a “Model of the View” meaning it is an abstraction of the View that also serves in data binding between the View and the Model. It could be seen as a specialized aspect of what would be a Controller that acts as a data binder/converter that changes Model information into View information and passes commands from the View into the Model. The ViewModel exposes public properties, commands, and abstractions. The ViewModel has been likened to a conceptual state of the data as opposed to the real state of the data in the Model.
This implementation/pattern wildly used in Silverlight application development. You can find the MVVM sample implementation using silverlight,
MVVM’s Command Structure
public class Command : System.Windows.Input.ICommand { public event EventHandler CanExecuteChanged; Func<object, bool> canExecute; Action<object> executeAction; bool canExecuteCache; EventHandler Executed; public Command(Action<object> executeAction) { this.executeAction = executeAction; this.canExecute = new Func<object, bool>(CanExecuteAction); } private bool CanExecuteAction(object parameter) { return true; } public Command(Action<object> executeAction, Func<object, bool> canExecute) { this.executeAction = executeAction; this.canExecute = canExecute; } #region ICommand Members public bool CanExecute(object parameter) { bool tempCanExecute = canExecute(parameter); if (canExecuteCache != tempCanExecute) { canExecuteCache = tempCanExecute; if (CanExecuteChanged != null) { CanExecuteChanged(this, new EventArgs()); } } return canExecuteCache; } public void Execute(object parameter) { executeAction(parameter); if (Executed != null) { Executed(this, new EventArgs()); } } #endregion }
Let’s see the MVVP Pattern implementation with an example:
1. Implement Model
Assume that we have a service,AppliationService and Model is UserDTO.
Service reference is given to the project where ModelView presents.
2. Implement ViewModel
INotifyPropertyChanged must be implemented to notify a data change through view to viewmodel or viewmodel to view
public class UserViewModel : INotifyPropertyChanged { #region Events public event PropertyChangedEventHandler PropertyChanged; #endregion #region Commands ApplicationServiceClient ApplicationService; public ICommand LoadViewsCommand { get; private set; } public ICommand LoadViewCommand { get; private set; } #endregion #region Properties private UserDTO _model; public UserDTO Model { get { return _model; } set { _model = value; OnPropertyChanged("Model"); } } private ObservableCollection _modelCollection; public ObservableCollection ModelCollection { get { return _modelCollection; } set { if (_modelCollection != value) { _modelCollection = value; OnPropertyChanged("ModelCollection"); } } } #endregion public UserViewModel() { this.LoadViewCommand = new Command(LoadView); this.Model = new UserDTO(); this.ModelCollection = new ObservableCollection(); } #region Command Invokers protected void LoadView(object parameter) { if(this.Model.Id!=null) { ApplicationService = new ApplicationServiceClient(); ApplicationService.GetUserAsync(this.Model.Id); ApplicationService.GetUserCompleted += (s, e) => { this.Model= e.Result; }; } else { this.Model=new UserDTO(); } } protected void LoadViews(object parameter) { ApplicationService = new ApplicationServiceClient(); ApplicationService.GetUsersAsync(); ApplicationService.GetUsersCompleted += (s, e) => { this.ModelCollection= e.Result; }; } } #endregion #region Methods protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } #endregion }
3. Implement View as Silverlight
<UserControl x:Class="SilverlightApplication1.MainPage" ... > <UserControl.Resources> <vm:UserViewModel x:Name="UserViewModel" /> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White" > <sdk:DataGrid AutoGenerateColumns="True" Height="153" Width="400" Name="dataGrid1" ItemsSource="{Binding Source=UserViewModel,Path=ModelCollection,Mode=TwoWay}" SelectedItem="{Binding Source=UserViewModel,Path=Model,Mode=TwoWay}" SelectionMode="Single" /> <Button Content="Load" Width="75" Height="23" HorizontalAlignment="Left" Name="btnLoadData" Command="{Binding LoadViewCommand,Source={StaticResource UserViewModel}}" /> </Grid> </UserControl>
Similar Topics:
- Repository Pattern in .net
- Implementing Unit of Work Pattern in .net
- Implementing Abstract Factory Pattern in .net
- Test Driven Development guide
- Implementing Factory Pattern in .net
- Dependency Injection (DI) Pattern in asp.net