Best way to close Window with MEFedMVVM - wpf

In my Application i have a MainWindow that import over MEFedMVVM the ViewModel:
xmlns:mefed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
mefed:ViewModelLocator.ViewModel="MainViewModel"
And now i have my ViewModel too that realize the ViewModel:
[ExportViewModel("MainViewModel")]
public class MainViewModel: ViewModelBase
In my ViewModel i have a ICommand property for closing the window. The event for closing can comes from anywhere. And with help from the Cinch Framework 2.0 i realize a Simplecommand with Execute methode.
Question
How can i Close the Window from my execute methode? Over the dependency injection i haven't a constructor i can't register an event or give the view as parameter to the viewmodel.
Edit
However, a possibility which I think is not nice:
Call this in the methode
Application.Current.MainWindow.Close()

You can achieve this by writing an ICommand that passes the Window instance in as a parameter.
A good example is available here: How can I assign the 'Close on Escape-key press' behavior to all WPF windows within a project?
In that post the ICommand is eventually bound to a KeyBinding (so that the Escape key can be used to close the window) but you would be able to bind the command to any button or invoke it from anywhere within the view. The important part is to use a RelativeSource on your command parameter binding to reference the Window that you want to close
Edit in response to comments
The command is a singleton, but there is no requirement for it to be - it is only a singleton because it is stateless and it makes the binding easier. It acquires a reference to the Window through binding, so for a UserControl you can just use:
<Button Command="{x:Static mynamespace:CloseWindowCommand.Instance}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" Content="Close My Parent Window" />
To be able to call it from view model code is slightly more complicated and needs a different approach; a good example can be found here: http://gallery.expression.microsoft.com/WindowCloseBehavior

Related

XAML minimize/maximize/close buttons through SystemCommands

There's a WPF class called SystemCommands. I've seen examples of these commands being used on buttons to perform common window tasks like maximize, minimize and close.
One of the examples I found looked like this (simplified):
<Window x:Name="MainWindow">
<Grid>
<Button Content="Close"
Command="{x:Static SystemCommands.CloseWindowCommand}"
CommandParameter="{Binding ElementName=MainWindow}" />
</Grid>
</Window>
When I start the application the button is disabled and I can't click it. Changing the IsEnabled property has no effect.
I managed to get the button to be enabled once, but I'm not able to reproduce it now. In any case, when it was enabled, nothing happened when I clicked it.
What must I do to get this button enabled and to actually close the window (or minimize/maximize)? I would really prefer it to be a XAML only solution if this is possible.
These are only predefined RoutedCommand(s) without any implementation. You must provide the implementation by yourself.
https://msdn.microsoft.com/en-us/library/system.windows.systemcommands
The commands in the SystemCommands class represent a set of common
commands that manage a Window. The properties in this class represent
RoutedCommand objects and do not provide the implementation logic for
the command. You can provide the logic for a command by binding the
command with a CommandBinding. Alternatively, the SystemCommands class provides static methods that implement the logic for the specified Window. You can pass a static method to a type that implements ICommand and that accepts a delegate. For more information, see the example in the InputBinding class.

ViewModel Handling Events

I saw an question here where OP asked about binding events to ViewModel. Basically ViewModel shall respresent an abstract View containing necessary data from Model so that the View may be also able to use Bindings. But to be able to fullfill all that the ViewModel must also conver most of the use cases which are happening in the View such as example if search textbox is empty the search button shall be greyed out. That works fine but lets add events to the game. It would be way easier if Button.Click where bindable to an EventHandler in ViewModel and inside the event handler you would be then able to use model objects.
Now my question is since WPF supports event driven programming why cant events be handled in ViewModel? How could I provide binding events funcionality?
Event handlers would sit in the view's code behind file. If you're using MVVM, then you'll want to minimise the amount of code in a code behind file.
WPF supports commanding, and the ICommand interface includes a CanExecute and Execute method. There are implementations of ICommand which allow these methods to be implemented on the view model.
Having said that, commanding also has its limitations, so you should consider using an MVVM framework when using MVVM. Something like Caliburn.Micro comes with Actions which also allow verbs on the view model to be invoked based on control events.
It is because the use of event explicitly breaks the MVVM pattern (as I am sure you are aware). However there is another way around this - by using the Attached Command Behaviour pattern. More information here.
Code for a small but great framework for attached commands is downloadable from here.
I hope this helps.
Edit. attached behaviour allow you to use events without breaking the MVVM pattern. The use is like
<Border Background="Yellow" Width="350" Margin="0,0,10,0" Height="35" CornerRadius="2" x:Name="test">
<local:CommandBehaviorCollection.Behaviors>
<local:BehaviorBinding Event="MouseLeftButtonDown"
Action="{Binding DoSomething}"
CommandParameter="An Action on MouseLeftButtonDown"/>
<local:BehaviorBinding Event="MouseRightButtonDown"
Command="{Binding SomeCommand}"
CommandParameter="A Command on MouseRightButtonDown"/>
</local:CommandBehaviorCollection.Behaviors>
<TextBlock Text="MouseDown on this border to execute the command"/>
</Border>

Bind a Parent window's event to UserControl inner handlers with MVVM

I have a parent window that loads a usercontrol inside a ContentControl. The parent window has a ToolBar with some buttons (i.e. Save button). I'd like to assign those buttons commands that would be handled inside the usercontrol.
I need to manage my own ICommand commands from the usercontrol's ViewModel so, to summarize: The user clicks on the "Save" button (on the main window) so the button fires an event which the userControl handles to save the information within the control.
Is this possible?
There are two ways of doing it.
Using MVVM,
Since your window contains UserControl, you need to set up so that Window has reference to the UserControl ViewModel(assume it is called UserControlViewModel). If you have a command in the UserControlViewModel, you could bind to that command, by calling: UserControlViewModel.Command something like:
<Button x:Name="Save" Content="Save" Command="{Binding UserControlViewModel.SaveCommand}">
Use the event handler
Again, your window needs to have a reference to the class where the event handler is implemented. you could have the following in your Window XAML file:
<Button x:Name="Save" Content="Save" Clicked="SaveButtonClicked"/>
Then in your code behind,
private void SaveButtonClicked( .... sender, .... e)
{
UserControlClass.SaveData();
// or using command
UserControlClass.MyCommand.Execute()
}
OK, you are trying to bind a child element's command to a parent window. First give a name to the usercontrol (e.g. x:Name = MyUserControl) and write a public command in the usercontrol's datacontext/viewmodel (e.g. ICommand MyCommand). Now in the button do this
<Button x:Name="SaveButton" Command={Binding ElementName=MyUserControl, Path=DataContext.MyCommand} />
This will bind the save buttons command to the command inside the datacontext of child usercontrol :)
BTW, if you are looking for the other way around (i.e. binding child command to parent in mvvm) you will need to use FindAncestor. You can have a look on my codeproject article
regarding this :)
This sounds like a case where Routed Commands could work. For the routed command, set the Command of the tollbar button to "Save". Then in the user control, add a command binding that listens for the "save" command.
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.CommandBindings>
<CommandBinding
Command="Save"
CanExecute="SaveCommand_CanExecute"
Executed="SaveCommand_Executed"
/>
</UserControl.CommandBindings>
</UserControl>
In the code-behind's event handlers for the command binding, just locate the viewmodel and invoke the save command on it's viewmodel. If you want a more purist MVVM approach, you could try Josh Smith's approach to routed commands with MVVM.
Using this approach, as long as the user control has focus somewhere inside of it, then the save button's Save command will route to the user control's command binding and exec the save command.
I think this might accomplish your goal of decoupling the toolbar button from the dynamically loaded user control in the ContentPresenter.
Well after a while I come back to this question. I needed to communicate with my parent window so i decided to perform the view-viewmodel datacontext binding right from the parent window, mainly because I want the child viewmodel to attach to events fired from its parent and also I can fire events to the parent in order to show messages outside the child control.
I know I may not be using the MVVM pattern completly but I wanted to have more control over these features.

Binding Commands Without Using the DataContext [silverlight+prism]

Hello I have a problem with binding commands to button inside datagrid.
Here should be explanation but it doesn't explain everything.
http://msdn.microsoft.com/en-us/library/dd458928.aspx
What should be in classes in namespace Infrastructure?
Can somebody show me a really basic sample of using this?
not just parts of the code...
The Prism Commanding QuickStart - included with the Prism drop should provide the simple code example you are looking for.
All data-bindings go against the current DataContext unless specified otherwise. The DataContext is inherited down the tree of controls unless a control specifically picks a DataContext.
For example your Button might look like this and would look for the SaveCommand on whatever the DataContext has:
<Button Command="{Binding SaveCommand} />
Your button could also look like this if you wanted to bind to a command exposed on your classes code-behind:
<UserControl x:Name="UserControl">
...
<Button Command="{Binding SaveCommand, ElementName=UserControl}"
...
</UserControl>
Using DelegateCommand is just a way of implementing the ICommand you bind to and that should be visibile in the Prism QuickStart.

MVVM What is the way of updating a UI after a command?

I'm learning MVVM through a project and I got stuck on something simple.
I have a Button that updates a ListView. I have a command in the ViewModel that make the right things but I want to select the new row and get the focus on a TextBox after I click the Button.
The question is: How do I update my UI after executing a command?
If I need to change my windows Title when an operation have been made, I use a property on the ViewModel that is binded to the Window's title and it's changed when I need it but, I don't know how to get focus on a control when a command has been executed.
Thank you.
To select the new row, add a new property to your ViewModel ("SelectedItem" for instance), and bind the ListView's SelectedItem property to it :
<ListView ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}">...
In the ViewModel, you just have to assign the new item to the SelectedItem property
To focus the TextBox, Mike's idea seems a good one
You could make an attached behavior. I'd suggest using the new Blend behavior framework, ie TriggerAction that contained this custom logic.
For your attached behavior you put on the button, give it a DP for an ICommand and maybe a DP of a ListView type.
On the "protected override void Invoke(object parameter)" of your TriggerAction, execute your ICommand, then you have reference to your ListView. Here you can do your custom code on it, like setting focus.
Your XAML may look something like this:
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Behaviors:CustomBehavior Command="CommandName" ListView="{Binding ElementName=myListView}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Button/>
I suggest looking at Mike Brown's ExecuteCommandAction behavior (download here), it's about almost 1/2 of what you need.
What about setting focus to the control in the code behind: textBox.Focus()
I consider everything you mention in your question to be GUI logic so I would add a Click event to the button to handle stuff that needs to happend in the GUI.
Hope this helps.
I think you need to use the Mediator pattern. Please see this:
Josh Smith's Mediator Prototype for WPF Apps
This is generally used in communicating with the View from the View-Model. Hope this helps.
In your case you need some way that the ViewModel notifies the View that it should set the focus on a specific control.
This could be done with an IView interface. The view implements this interface and the ViewModel can call a method of the View over this interface. This way you have still the View and ViewModel decoupled of each other.
How this can be done is shown here:
WPF Application Framework (WAF)
http://waf.codeplex.com

Resources