Is it possible to create a command behavior using Prism's CommandBehaviorBase class for Silverlight's grid? I know that it is only intended for actual controls, so I was wondering if anyone might know if a workaround. I would like to create an attachable mouse over behavior for a grid, that executes a specific command, and ideally would like to use Prism for this approach, just can't seem to use CommandBehaviorBase for a Grid.
Thanks.
The arguably easier way to achieve this is to use Triggers. Doesn't require you to write any code, all you have to do is this:
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<si:InvokeDataCommand Command="{Binding DoSomethingCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...
</Grid>
Here the DoSomethingCommand (defined in a ViewModel) will trigger when MouseEnter event is fired on the Grid.
Related
I have a Prism application and I'm attempting to bind PreviewMouseDown and PreviewMouseUp button events in my view to commands in my view model. When I run the code I see the following exception:
As a workaround, I'm currently binding to methods in the view and use a reference to the data context of the view model to execute the command. This works but doesn't seem correct because the view now has knowledge of the view model.
What is the proper way to handle something like this?
You cannot bind events to commands like, for example, the Command property of a button.
Luckily, you don't need to, because you have the Command property. It even disables the button if the command returns false from CanExecute.
If you have something other than a button or something other than MouseDown, you can use InvokeCommandAction (from Prism or from Interactivity)...
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<prism:InvokeCommandAction Command="{Binding MyCommand}"/>
<!-- or -->
<i:InvokeCommandAction Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Mouse gestures can be bound to commands using the MouseBinding InputBinding,
for example:
<Grid.InputBindings>
<MouseBinding Command="{Binding MyCommand}" Gesture="LeftClick"/>
</Grid.InputBindings>
In that example, the LeftClick gesture is used. What is the full list of gesture strings? I'm looking for a left mouse button down gesture, if it exists.
That is a MouseAction value. You can see possible values in the documentation. Mouse down is not a built-in gesture. Only various clicks and double clicks are in the enumeration.
It is possible to make your own input bindings by creating classes that extend InputBinding and InputGesture. You can reference the implementation of MouseBinding for an example. Alternatively, you can find a different way to accomplish whatever it is you are trying to do.
I'm looking for a left mouse button down gesture, if it exists.
That would be the LeftClick mouse action that you are currently using.
If you want to invoke a command when the MouseLeftButtonDown event occurs, you could do this using an interaction trigger:
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown" >
<i:InvokeCommandAction Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Please refer to the following blog post for more information about this.
Handling events in an MVVM WPF application: https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/
The EventTrigger class is included in th Expression Blend SDK which you can download from here: http://www.microsoft.com/en-us/download/details.aspx?id=10801.
Hooking into it using code behind is trivial, but I can't work out a good way of handling it using MVVM.
I'll answer my question.
You can use Interaction.Triggers.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Completed">
<i:InvokeCommandAction Command="{Binding CompletedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
One method I can think at the back of my mind now is, other than putting an EventTrigger for storyboard animation, you should also put up a DataTrigger. The DataTrigger should trigger on the same Property being animated, and the trigger value should be the value when the animation completes. If this control is your own custom control (or UserControl), you can create a new dependency property HasCompletedAnimation on it, and bind it to the ViewModel. If the control is neither a custom control nor UserControl, you can try using that control's Tag property.
I am implementing MVVM pattern in wpf application. We have a textbox that calls event handler on KeyUp event. I binded text of that textbox with property tb_property which is in ViewModel. The idea that I have is to have ViewModel implement INotifyPropertyChange and to bind command object that does what event handler did and implements ICommand to the change on that tb_property. Is this a good idea, and how should I do it? I am trying to get rid of most of the events from View. Thank you in advance.
Yes, depending on what MVVM framework you are using you can bind the control's event to a iCommand on the viewmodel.
I use MVVM light so they have a build in realaycommand for just such a condition. I then bind the control's event int he following way:
add the following to your usercontrol/window opening tag (the cmd uses the mvvm framworks implementation of icommand):
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
Then I add the command binding to the control like:
<TextBox Grid.Row="1" Text="{Binding tb_property, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="YourEvent">
<cmd:EventToCommand Command="{Binding YourCommandPropertyOnVIewModel}" CommandParameter="OptionalCommandParameter"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
This way you move all your "event" to your view model and I love this because other controls can use the same command.
Hope this helps
JK
I've setup a windows store app using Prism. I have a need to use a command to notify the viewmodel of an action, but I cannot use a button in this case. Is there a way to fire a command defined in a viewmodel from the view, but in an agnostic fashion, so that the view/viewmodel aren't tightly coupled?
if(command.CanExecute(parameter))
command.Execute(parameter);
If you would like to put calling command in code behind, you can do what Aron suggested.
If you do not like code behind or it is hard to have code behind, like DataTemplate, you should think what condition to trigger the command. If you command is trigger by some event, you can use Prism like below and you also can choose some other triggers built in Prism or write trigger by yourself.
<i:Interaction.Triggers>
<i:EventTrigger EventName="FrameworkElement.Loaded">
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
If you have more complex logic, you can write a Behavior with a ICommand DependencyProperty. Binds your command on the ViewModel to the DependencyProperty and consume it in your Behavior.