WPF MVVM - Activate ViewModel-command by use of hot keys from MainWindow - wpf

I have an MVVM application in which the MainWindow contains a grid with several views.
In one of the viewmodels there is a command which I can activate by using hot keys in its corresponding view. I can only activate the command when I am placed in the part of the MainWindow that contains the specific view.
The following code works fine, if I only want to be able to activate the command in the specific view:
ComponentView.xaml:
...
<UserControl.InputBindings>
<KeyBinding Gesture="CTRL+U" Command="{Binding Path=UploadCmd}"/>
</UserControl.InputBindings>
</UserControl>
I would like to be able to activate the command by using the hot keys from any part of the MainWindow.
This is my failed attempt to do the keybinding in the MainWindow, so that the command can be activated from anywhere:
MainWindow.xaml:
<Window x:Class="MyProgram.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:view="clr-namespace:MyProgram.View"
xmlns:vm="clr-namespace:MyProgram.ViewModel"
...>
<Grid>
// Grid content
</Grid>
<Window.DataContext>
<vm:ComponentViewModel>
<KeyBinding Gesture="CTRL+U" Command="{Binding Path=UploadCmd}"/>
</vm:ComponentViewModel>
</Window.DataContext>
</Window>
Is it possible to somehow let the application know where the command is directly in the xaml?

Three options I can think of:
You could place your commands in your main window and then use relative source binding from the child views to the command in your main window.
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type Window}}}
If you are using an mvvm framework, there is often a way to message / communicate between viewmodels. This is usually not the best solution but can be used in the right circumstance.
Use IOC / Dependecy Injection to create a service that is instantiated as a singleton in your viewmodellocator. Then inject this service implementation into the parent and child viewmodels constructors. Then you can call functions/properties from that service from the parent viewmodel that can be accessed by the child viewmodels. I use this for navigation purposes.
What are you trying to do with those commands?
Hope this helps

Related

How do I bind a button in a Shell, to a Command defined in a loaded module's viewmodel?

The scenario is this:
I have an application developed in WPF, MVVM, Prism 6.3.0. This app considers
Shell.xaml (the shell)
UserControl1.xaml (inside a module, independient Class Library)
When I click on the Button defined in the Shell, I expect the command being executed and the condition defined in CanExecute be verified. But, this command is defined into the ViewModel class that's the view model of the module (in this application will be more than one module, loaded as Prism implements this traditionally).
To be called, I tried to define a localviewmodel into the resources collection of the Shell. This triggers the command, but doesn't triggers the condition CanExecute.
If I put the XAML code defined in the user control inside the module, (in other words, If I code a simple app with no use of Content region manager) a single-page XAML app, the command verifies the CanExecute without a problem. My best guess is a problem of binding the command defined in the module viewmodel, into a button in the Shell. Having read a lot about it, I just don't get the right way of declaring the binding.
Here's an example:
<Telerik:RadRibbonView x:Name="BarraHerramientas" Grid.Row="0"
DockPanel.Dock="Top"
ContentHeight="130"
Height="160"
Template="{DynamicResource RadRibbonViewStyle}"
MinimizeButtonVisibility="Visible"
HelpButtonVisibility="Visible" Background="Red">
<Telerik:RadRibbonTab Header="1"
Style="{DynamicResource RadRibbonTabStyle}"
IsSelected="True"
TabIndex="0">
<Telerik:RadRibbonGroup Header="RibbonGroup1"
DialogLauncherVisibility="Visible">
<Telerik:RadRibbonButton CollapseToMedium="Never"
CollapseToSmall="WhenGroupIsMedium"
IsAutoSize="True"
LargeImage="Agregar.png"
Size="Large"
SmallImage="Agregar_16x16.png"
Text="Add..."
Command="{Binding AddRecordCommand, Source={StaticResource LocalViewModel}}"
CommandTarget="{Binding ElementName=MyRecords}"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" "
Telerik:ScreenTip.Description="..." />
</Telerik:RadRibbonGroup>
</Telerik:RadRibbonTab>
</Telerik:RadRibbonView>
Where MyRecords is the name of the GridView that holds the data, and LocalViewModel is the key of the instance of the ViewModel defined in the loaded module. So, there's two instances in a point of time of LocalViewModel, the one defined as a resource in Shell.xaml, and the one defined into the loaded Module that holds the "MyRecords" GridView.
Using a one-page example, this works flawless, of course. And because I need to write a few modules, each one defines it's own ViewModel, or more than one. So, thats because I need to use commands defined into the different module's viewmodels, from the Shell. If I declare each ViewModel in the shell (a LOT of data coming in) probably will be a performance issue.
So, how can I call a command (from the shell) that is defined in a ViewModel as a resource in a module being loaded "on demand"?
Thanks everyone.
There are a number of ways to accomplish what you want. One approach would be to use a CompositeCommand. If your ShellViewModel will always contain the data you use as a parameter this will work for you. Each ViewModel can subscribe the the parent CompositeCommand and whenever the CompositeCommand is invoked all registered VM Commands will be invoked too. You can see a sample of CompositeCommands here:
https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/12-UsingCompositeCommands
Another approach would be to have your ribbon buttons injected with each view you inject into the shell. So each view will know which tabs need to be added/removed to the ribbon as you add/remove the views in the shell region. You can see how to do that in my Pluralsight course Prism Problems & Solutions: Loading Dependent Views:
https://www.pluralsight.com/courses/prism-problems-solutions

mvvm Pass button click to parent

Note: this is a different question to the one here: Pass dependency property to child view
I am currently creating a usercontrol in wpf which consists of several 'screens' that the user will click through.
For each 'screen' I have created a view with it's own viewmodel (e.g. View1.xaml, View2.xaml). The main usercontrol can then access these views:
<UserControl.Resources>
<local:ModuleBaseViewModel x:Key="ViewModelDataSource" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModelDataSource}}">
<local:View1 Visibility="Visible"/>
<local:View2 Visibility="Hidden"/>
</Grid>
I would like to pass a button click from a view back down to the parent usercontrol so that I can hide that view and show the next one. Can someone explain to me how to do this?
Thanks!
If you are using MVVM and WPF, chances are you are using an IoC container. Almost every IoC container contains a method of publishing an event and then subscribing to that event. In Prism, the code looks something like this:
EventAggregator.GetEvent<SomeEvent>().Publish(ParametersHere)
I would suggest you look at your options for publishing events and reacting to them. Then your parent view model can respond to the children's events.

MVVM WPF - Viewmodel commandbinding

Iam using MVVM model and I have three usercontrols in a WPF Main window and each usercontrol has datacontext set to different viewmodels in the xaml.
The main window is also attached to a different viewmodel in the datacontext. Mainwindow has three buttons and should be bound via command binding, How can we bind the main window buttons to corresponding usercontrol view model Icommand via xaml?
It's difficult to tell if this is a good solution because there are a lot of missing details about your application architecture.
Based on the premise "I have a window that contains 3 user controls and I want buttons on the window to activate commands on the viewmodels of the controls", one solution could be:
<Window>
<UserControl Name="Control1" />
<UserControl Name="Control2" />
<UserControl Name="Control3" />
<Button Command="{Binding ElementName="Control1", Path="DataContext.Cmd"}" />
<Button Command="{Binding ElementName="Control2", Path="DataContext.Cmd"}" />
<Button Command="{Binding ElementName="Control3", Path="DataContext.Cmd"}" />
</Window>
This is a bit subjective, but in my opinion viewmodels should not be serving more then one view.
The MainWindow's viewmodel should be totally independent from the UserControl's models. I would suggest using a publish/subscriber pattern for sending "events" through your application that handle widely used functionality (see for example Event Aggregator).
If you can't access the ViewModels via a direct binding from DataContext of the MainWindow (i.e. if the three ViewModels aren't in the MainWindow's ViewModel), you can just do this :
<Button
Name="Button1"
DataContext="{Binding DataContext, ElementName=UserControl1}"
/>
This should work if I understood well what you're asking.

PRISM UserControl and ServiceReference

I'm using MVVM in my project and here is my question. I have a View and corresponding view-model with service reference. This view contains UserControl, which have another UserControl and it also contains nested UserControl. Last UserControl have a method which creates a popup. And in this popup i need service reference from view model. Each user control has own DataContext.
Code explanation.
View xaml:
<UserControl DataContext="{Binding ViewModel}">
<FunctionsList/>
</UserControl>
FunctionsList xaml:
<UserControl>
<Function1/>
<Function2/>
<Function3/>
<Function4/>
</UserControl>
Function3 xaml:
<UserControl/>
Function3 code behind contains CreatePopup method, which creates dialog with a UserControl Function3Popup as Content. And Function3Popup should have Service reference.
What is the best practice here? I have awful solution to pass reference using binding but it seems discouraging to me.
Well, after all I've implemented popup with own ViewModel and resolved it from parent control using command binding in the nested child control. I think it's the best solution here.

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.

Resources