In this message thread bsimser needs to close the View from the Presentation Model. In MVP this would not be a problem because the View instantiates the Presenter and then hands the presenter a reference to itself. In the Presentation Model this isn't the case, the Presentation Model is "an abstract of the view that is not dependent on a specific GUI framework"; there won't be a reference to the view in the Presentation Model. You'll see something as follows where the data is "pulled" from the model.
Note: All references will be in the context of the CompositeWPF Commanding.sln solution. The changes noted below provide a POC for bsimser' requirement.
OrdersEditorView.Xaml
<DataTemplate DataType="{x:Type models:OrderPresentationModel}">
<RowDefinition /> <<== Added an extra row for demo
I'll show how we can meet bsimser's requirement in a decoupled manner - the only dependency will be on the "Window" class.
In the same OrdersEditorView.xaml file (referenced above) I added the following Button. The somewhat busy Binding basically will search up the logical tree until it finds a control of type Window, once found it will set a reference to it in the CommandParameter.
<Button AutomationProperties.AutomationId="Close"
Grid.Row="7"
Grid.Column="1"
Content="Close"
CommandParameter="{Binding RelativeSource={
RelativeSource FindAncestor,
AncestorType={x:Type Window}}}"
Command="{Binding CloseCommand}">
</Button>
</Grid>
</DataTemplate>
</UserControl.Resources>
I then added the following code to the OrderPresentationModel.cs to handle the new Button click:
The following provided for your copy/paste convenience:
public DelegateCommand<object> SaveOrderCommand { get; private set; }
public DelegateCommand<object> CloseCommand { get; private set; }
public OrderPresentationModel()
{
SaveOrderCommand = new DelegateCommand<object>(Save, CanSave);
CloseCommand = new DelegateCommand<object>(Close, CanClose);
DeliveryDate = DateTime.Now;
PropertyChanged += OnPropertyChangedEvent;
Validate();
}
private bool CanClose(object arg)
{
return this.errors.Count == 0 && Quantity > 0;
}
private void Close(object obj)
{
//Save the order here.
Console.WriteLine(String.Format(CultureInfo.InvariantCulture,
"{0} saved.", OrderName));
Window view = obj as Window;
if (view == null)
throw new InvalidOperationException(
"Could not find view in " + GetType().Name);
view.Close();
}
With the above noted changes you can close the view with the click of the [Close] button; reference FLASH DEMO HERE
Source available at http://www.CodePlex.com/SDMS | Change set 24041
CompositeWPF | QuickStarts | Commanding | Commanding project (startup)
Tags:
compositewpf,
binding,
ancestor
Categories:
CompositeWPF