I am learning WPF using the MVVM pattern. I am trying to use the InvokeCommandAction behavior on a button. In Blend, I placed a button on my view. I then dragged the InvokeCommandAction onto the button.
Blend displays the Properties tab. The trigger is set to "Click". I set Command to CloseCommand : (IComamnd) in my view using the "Create Data Binding" dialog.
This generates the following XAML
<Button x:Name="CloseApp" Content="Close" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding CloseCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
CloseCommand is a RelayCommand : ICommand from MSDN. The project compiles, but when I click on the button, the command does not execute. Any ideas, or sample code to point me to.
Related
In WPF MVVM application, I need same functionality for multiple controls - for example certain button does same thing as certain menu item. It is piece of cake with MVVM Light's RelayCommand, but I am now using Caliburn.Micro, where almost everything is based on conventions. So two controls can not have same x:Name="AddItem", which is used by CM to determine method for executing in ViewModel. Is there any simple way to solve this?
Yes, it's simple, but verbose. You need to use the "long format". Let's say you have one method IncrementCount on your ViewModel:
// Handling event
public void IncrementCount()
{
Count++;
}
And your View has:
<Button Name="ButtonOne">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="IncrementCount" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Name="ButtonTwo">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="IncrementCount" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Both buttons will call your IncrementCount method.
EDIT
Add these namespaces
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cal="http://www.caliburnproject.org"
You may see this Caliburn starting project using the snippets above.
How can I let my controls on the window know that their states should be changed. I have to use ICommand and since controls can have different states (Enable/Disable , Checked/Unchecked ...) have to handle them with VisualStateManager.
This could be a possible scenario:
When Record button is clicked(Checked) the other controls in the window should be uncheckable and once the recording is finished they should be checkable and many other scenarios.
Any help would be really appreciated.
Thanks.
You can achieve it with the help of interaction and interactivity. See if it helps.
Add below references in your XAML
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
You can bind your ICommand and provide a VisualState name that will be applied when Button is clicked
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding YourICommand}" />
<ei:GoToStateAction StateName="YourVisualStateName" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
If you don't have Blend 4, you can install the Blend 4 SDK to get the current behavior assemblies.
The MVVMLight EventToCommand can be used to fire an ICommand on your viewmodel quite easily.
<DataGrid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<GalaSoft_MvvmLight_Command:EventToCommand
Command="{Binding ProductSelectionChangedCommand, Mode=OneWay} "
CommandParameter="{Binding SelectedItems, ElementName=gridProducts}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
In this instance the SelectionChanged event belongs to DataGrid, and the Interaction.Triggers xaml is nested directly inside DataGrid.
I cannot figure out how to do the same when the event is a DataGridRow (which has its own events for each row).
I managed to do this, but it involves a handler function which I'd like to avoid :
<DataGrid>
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="DataGridRow.MouseEnter"
Handler="Row_MouseEnter"/>
</Style>
</DataGrid.ItemContainerStyle>
</DataGrid>
In the Row_MouseEnter event (on my .xaml.cs file) I just 'find the command' on the ViewModel and trigger it programatically.
I'd really like to know if there's a way of doing the same directly with Interaction.Triggers
(FYI: What I'm doing is I have a panel above the grid which displays details of the row that the mouse is over before clicking on it - which triggers a detail view).
Yeah you can directly bind to the command in your ViewModel by creating your own custom behaviour class and using it in xaml file. These links might get you started - Binding using interactivity and Binding through interaction in MVVM
How to convert the Checkbox.checked routed event to the command for MVVM pattern?
Reference-Consider the button click routed event, When we assign the command for button then button.click event is considered as command. It executes respective that command.
I googled for it, i got the solution with EventBehaviourFactory. Is it possible without using the EventBehaiourFactory?
It is a common requirement in WPF. The most widely used solution is using Interactivity from the Blend SDK:
Add this xmlns namespace to your xaml:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Then you can do:
<CheckBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding MyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
Of course, you need to add System.Windows.Interactivity.dll to your project, located (for me at least) at: C:\Program Files (x86)\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\WPF\System.Windows.Interactivity.dll
I want to use hyperlink in wpf xaml. Whenever mouse comes over the hyperlink, it should show image related to that hyperlink and when mouse gets away the image should disappear. How to go about this using bindings. I am using mvvm light.
Kindly Suggest.
Thanks
The basic framework of what you will need, if you want to accomplish this in an MVVM style is...
You will need to start by setting up a Behavior to Command the Hyperlinks MouseEnter MouseLeave events.
<Hyperlink NavigateUri="Uri">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<Command:EventToCommand Command="HoverCommand" PassEventArgs="True" />
</i:EventTrigger>
<i:Interaction.Triggers>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<Command:EventToCommand Command="HoverCommand" PassEventArgs="True" />
</i:EventTrigger>
<i:Interaction.Triggers>
Link text.
</Hyperlink>
Now setup a control that will hover when the its DataContext is not null
Use the command to set the controls DataContext on hover to the Uri of the image, on Leave set the datacontext to null.