What the best way to use command binding under Microsoft.Toolkit.MVVM - c#

I'm using Microsoft.Toolkit.MVVM, in doc
we can use binding Button command like:
<Button
Content="Click me!"
Command="{Binding ButtonClickCommand}"/>
But for ListView, I have to write like with Behaviors, this code is to long:
<ListView>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
So why can't use below code instead? This is simple, but not working.
<ListView SelectionChanged={Binding SelectionChangedCommand}/>

the simple answer is the type of the object
in button Command is ICommand and in the ListView the SelectionChanged is an event and not ICommand , this why you need to use eventTrigger which is an "addon"
if you look at it from MVVM perspective the button is here to bind a command the ListView has SelectedItems collection that you can bind to and not the event , but that's more of a choice you need to make (I think that your code looks fine once you are used to it)

Related

WPF Command not executed when viewmodel changes

I'm new to WPF and I don't know why binding from the viewmodel does not execute the specified command.
<CheckBox x:Name="CheckBoxName" Content="MyCheckBox" IsChecked="{Binding Restrictions.MyCheckBox}" Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=CheckBoxName}"/>
When I check the checkbox in the view, MyCommand is executed as expected, but when I set the IsChecked property from the viewmodel using binding, the command is not executed.
Does anyone have any idea why it's happening? How can I execute the command from viewmodel using binding?
Thanks you very much!
As far as I know, the Command is executed on the "Click" event of the base "ButtonBase" class, which is not triggered if you change the IsChecked Property via Binding.
One solution would be to attach a trigger to the Checked and Unchecked event, which triggers your command.
First you need to add the namespace
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
And for your checkbox
<CheckBox x:Name="CheckBoxName"
Content="MyCheckBox"
IsChecked="{Binding Restrictions.MyCheckBox}"
Command="{Binding MyCommand}"
CommandParameter="{Binding ElementName=CheckBoxName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding Path=IsChecked, ElementName=CheckBoxName}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding Path=IsChecked, ElementName=CheckBoxName}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Checkbox>

How to use Composite command in mvvm

Intro
I'm working with WPF with MVVM-Light application
Goal
I have to invoke two commands from the same event, Is this possible using MVVM.?
Xaml look like this
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding Command1}" PassEventArgsToCommand="False" />
<command:EventToCommand Command="{Binding Command2}" PassEventArgsToCommand="False" />
</i:EventTrigger>
</i:Interaction.Triggers>
Problem
When hooking two commands only one of them is invoked while triggering the event.
Q1 How to invoke two commands in a event?
I have heard about Composite commands in PRISM
For example, the CompositeCommand class is used in the Stock Trader Reference Implementation (Stock Trader RI) in order to implement the SubmitAllOrders command represented by the Submit All button in the buy/sell view. When the user clicks the Submit All button, each SubmitCommand defined by the individual buy/sell transactions is executed.
.
Q2 Is there anything like this in MVVM ?
Try using 2 event triggers:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding Command1}" PassEventArgsToCommand="False" />
</i:EventTrigger>
<i:EventTrigger EventName="Loaded">
<command:EventToCommand Command="{Binding Command2}" PassEventArgsToCommand="False" />
</i:EventTrigger>
</i:Interaction.Triggers>

call functions of viewModel from user control

I have View1, ViewModel1 (which is DataSource for View1) and UserControl (TextBlockComboBoxUC).
View1 contains TextBlockComboBoxUC in XAML like this :
<vwKomp:TextBlockComboBoxUC
ComboBoxItemSource="{Binding Path=ZoznamStatov, Mode=OneWay}"
ComboBoxSelectedValue="{Binding Path=TrvalaAdresa.Stat, Mode=TwoWay}">
</vwKomp:TextBlockComboBoxUC>
TextBlockComboBoxUC contains TextBlock and ComboBox.
How can I call the method from ViewModel1 when ComboBox's SelectionChanged event is raised?
I suppose somehow via delegates, but I have no information about UserControl in ViewModel1.
If you don't mind using the MVVM Light library, I think you can set up a trigger for that event to call the command:
<vwKomp:TextBlockComboBoxUC
ComboBoxItemSource="{Binding Path=ZoznamStatov, Mode=OneWay}"
ComboBoxSelectedValue="{Binding Path=TrvalaAdresa.Stat, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" >
<cmd:EventToCommand
Command="{Binding YourSelectionChangedCommandHandler}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</vwKomp:TextBlockComboBoxUC>
Where:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
Source: http://www.danharman.net/2011/08/05/binding-wpf-events-to-mvvm-viewmodel-commands/

How to fire a command on double-click listbox item using MVVM?

I'm trying to launch an ICommand when the user double-clicks on a listbox item. Also, I'm trying to do this using the MVVM pattern.
In this XAML, the key press "p" works perfectly. When I double click on the list box, the command never starts. I've set a break point to confirm "PlayVideoCommand" is not called with a double-click. Am I missing something or do I have to use Setter (which I'm not familiar with)?
<ListBox Name="SmallVideoPreviews" Grid.Column="1" MaxHeight="965"
ItemsSource="{Binding BrowseVideos}"
ItemTemplate="{StaticResource BrowseTemplate}">
<ListBox.InputBindings>
<KeyBinding Key="p"
Command="{Binding PlayVideoCommand}"
CommandParameter="{Binding ElementName=SmallVideoPreviews, Path=SelectedItem}"/>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding PlayVideoCommand}"
CommandParameter="{Binding ElementName=SmallVideoPreviews, Path=SelectedItem}"/>
</ListBox.InputBindings>
</ListBox>
Both double-click and "p" should execute the same command. When using the mouse, I can see the listboxitem is selected. I have a hunch that the MouseBinding Command property is not a dependency property but I don't know how to confirm this.
What's happening in your sample is that the listbox itself is reacting to the double click, but only in the part of it's area that is not covered by a list box item.
You need the event handler to be tied to the listboxitem.
Some ways to do it are here:
Double Click a ListBox item to open a browser
And some discussion about why a little code-behind in MVVM is not necessarily a terrible thing:
Firing a double click event from a WPF ListView item using MVVM
More discussion:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9fb566a2-0bd6-48a7-8db3-312cd3e93340/
It seems that the ListBox doesn't handle double click on a ListBoxItem. This is a good answer:
Can't bind Command to ListBox
One could argue weather or not code-behind is terrible, but it ís possible use a command. Add the LeftDoubleClick gesture to the ItemTemplate like this:
<UserControl.Resources>
<DataTemplate x:Key="BrowseTemplate" >
<StackPanel >
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding DataContext.PlayVideoCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Mode=OneWay}"
CommandParameter="{Binding }" />
</StackPanel.InputBindings>
<TextBlock Text="{Binding }" Width="50" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>

MVVM WPF bindings with RelativeSource

<DataTemplate DataType="{x:Type local:TestModel}">
<Button Content="Button" " Margin="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<mvvm:EventToCommand
Command="{Binding ImageClick, Mode=OneWay}"
MustToggleIsEnabledValue="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
Hi all,
Above I have a data template which is switching on certain data type using a data template. I am using the mvvm pattern. I want to be to bind to the ImageClick property.
I was able to do this before, but since I have moved the button inside the data template I am unable to bind to that property.
I think I need to use Relative source for the binding but am really unsure how to do it.
Help on this would be amazing.
Thanks.
You may try the below.
<Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type YourViewModel}}, Path=DataContext.ImageClick}" />
I think it would help you..

Categories

Resources