OK so I am (very) new to WPF but have 13 years with Win-forms, so no newbie. I am writing a new system and decided to break the ice with WPF using the MVP-VM pattern as I am familiar with MVP.
Now I am also reusing my own (composite) architecture which has the UI or presentation layer in a project separate from the Presenters and View models. One of the main benefits to this approach is that the Presenter layer or Base layer has all the presentation/command/controller logic and no reference to UI matters. The Main IDEA is that this layer has no reference to any UI assemblies like Winforms or WPF.
The ISSUE: IN Xaml, I have a menu item 'Exit' which I want to bind to the View model. Every example of this that I have seen uses ICommand.. which is housed in Presentation.core... the view model is in the presentation layer and therefore does not have a reference to the Presentation.Core..
The Xaml thus far is
<Window x:Class="Homestead.Wpf.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="244" Width="490" xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="23"/> <RowDefinition Height="*"/> <RowDefinition Height="23" /> </Grid.RowDefinitions> <Menu Grid.Row="0"> <MenuItem Header="File"> <MenuItem Header="Exit" /> </MenuItem> </Menu> <StatusBar Grid.Row="2" > <StatusBarItem > <TextBlock Text="{Binding Path=StatusMessage}" /> </StatusBarItem> <StatusBarItem HorizontalAlignment="Right" MinWidth="120"> <TextBlock Text="{Binding Path=UserName}" /> </StatusBarItem> </StatusBar> </Grid> the view model thus far is
public class ShellViewModel : ViewModelBase { #region Private Variables private string _status = string.Empty; private string _userName; #endregion #region Public Properties public string StatusMessage { get { return _status; } set { _status = value; OnPropertyChanged("StatusMessage"); } } public string UserName { get { return _userName; } set { _userName = value; OnPropertyChanged("UserName"); } } #endregion #region Commands // No reference to ICommand... WTF #endregion } - is there any alternative to this pattern..(without using code behind)
- How does this work with Menu items added at runtime, amusing there is a way.
Must I redesign or break the design pattern to use WPF? please guide me.
There is one possibility that I can see and that is to Interface out the ViewModel as well as the View.. I have a Controller that creates the Presenters that usually passes in to the presenter the implementation of the view. I.e a typical Presenter constructor would be
public ErrorMessagePresenter(IErrorMessageView view) { View = view; View.Presenter = this; } The controller code is thus
public ErrorMessagePresenter CreateErrorPresenter() { return new ErrorMessagePresenter(_viewFactory.CreateErrorMessageView()); } now I know that this is reversed but literally the UI layer is only concerned with UI matters, everything else including navigation is handled in the Base layer or below..