I am having trouble and don't know what to pass as command parameter.
<triggers:Interactions.Triggers>
<triggers:EventTrigger EventName="ItemClick">
<triggers:InvokeCommandAction Command="{Binding MenuItemClick}" CommandParameter=""/>
</triggers:EventTrigger>
</triggers:Interactions.Triggers>
This is inside gridview declaration. I want to recieve gridview clicked item in binded delegate as parameter.
You can set the PassEventArgsToCommand property of the InvokeCommandAction to true which will allow to pass ItemClickEventArgs pp to your command.
<triggers:InvokeCommandAction
Command="{Binding MenuItemClick}" PassEventArgsToCommand="True"/>
or see this article which provides more reliable solution from view point of better design.
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>
I use Prism in my project and I want to have a converter in the event trigger to convert the event argument to my class model.
The problem is that the converter is not called in the Prism implementation and sends the event arguments directly to the view model.
This is my XAML code:
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="RecordExpanding">
<prism:InvokeCommandAction Command="{Binding RowExpandCommand}"
CommandParameter="{Binding Mode=OneWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=events:RecordExpandingEventArgs}, Converter={StaticResource DataGridRecordExpandingConverter}}" />
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
It does not work, because your assumptions about the parameter binding are wrong. The Prism InvokeCommandAction automatically assigns the event arguments of the associated event as command parameter, if you do not specify a parameter yourself. In the latter case it is overwritten.
Your parameter binding uses a RelativeSource. This is only suitable, if you want to bind to properties of an ancestor of your control in the logical tree or the control itself. This does not work with events, because they are not part of the tree.
However, there is a solution to your problem. You can specify which property of your event arguments will be passed as command parameter using the TriggerParameterPath property. Let us assume that your RecordExpandingEventArgs have a property called Record that you want to pass, then your action looks like this:
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="RecordExpanding">
<prism:InvokeCommandAction Command="{Binding RowExpandCommand}"
TriggerParameterPath="Record"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
Note that this also works for nested properties like Record.Cells. Alternatively, you can also use EventToCommand from MVVM Light framework, where you can explicitly specify an event arguments converter.
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 have a list view that is populated from a mysql table, I want to be able to double click on a item in the listview and bring up a new window with more information. How do I pass the first column value to the new window (this is the id of the item)? This way I can make another query to get the rest of the info about the item.
Was having a similar issue with a ListBox wanting to open a window (Different View) with the SelectedItem as the context (in my case, so I can edit it).
The three options I've found are:
1. Code Behind
2. Using Attached Behaviors
3. Using Blend's i:Interaction and EventToCommand using MVVM-Light.
I went with the 3rd option, and it looks something along these lines:
<ListBox x:Name="You_Need_This_Name"
ItemsSource="{Binding Your_Collection_Name_Here}"
SelectedItem="{Binding Your_Property_Name_Here, UpdateSourceTrigger=PropertyChanged}"
... rest of your needed stuff here ...
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Command:EventToCommand Command="{Binding Your_Command_Name_Here}"
CommandParameter="{Binding ElementName=You_Need_This_Name,Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
That's about it ... when you double click on the item you want, your method on the ViewModel will be called with the SelectedItem as parameter, and you can do whatever you want there :)
What is meant with MVVM is that you will have for example a ViewModel containing a property SelectedThing bound to the SelectedItem of the listview and a command that gets executed using EventCommand on the MouseDoubleClick event of the View which will execute in the end the operation you want on the SelectedThing which could be also passed in as parameter to the command also by binding.
I'm having some issues when using a converter with multiple bindings in a Silverlight project. The task is to disable a button when it is clicked, depending how four properties are evaluated in the custom converter.
The flow of the task is as follows:
Converter fired when initialising buttons
Button clicked and Command fired in ViewModel
Keep a record of the Id of the button in one viewModel property
In ViewModel fire OnPropertyChanged for one of the three view model properties
This should fire the converter
Everything is working apart from the last step. During the second last step, I can see the Property being accessed again after the OnPropertyChanged is fired. So I can't understand why the binding doesn't pick this change up and fire the converter. I'm thinking it may be due to the button item being in a datagrid and the bindings using Path & ElementName.
I'm using a MultiBinding solution for Silverlight 5 from here.
And I've seen this question but its solution isn't available in Silverlight (Binding.IndexerName).
So on the actual control I have a datagrid where each row has a textblock and a button.
The Button IsEnabled is bound to a Converter with three values from the ViewModel (properties A-C) and one from the datagrid.ItemSource (Id).
<Button Tag="{Binding Id}"
IsEnabled="{multibinding:MultiBinding Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
Source1={Binding Path=DataContext.PropertyA, ElementName=LayoutRoot},
Source2={Binding Path=DataContext.PropertyB, ElementName=LayoutRoot},
Source3={Binding Id},
Source4={Binding Path=DataContext.PropertyC, ElementName=LayoutRoot},
Converter={StaticResource myConverter}}">
The Button Click event is bound to a command on my viewModel.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Path=DataContext.ClickCommand, ElementName=LayoutRoot}"
CommandParameter="{Binding Id}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Firing the OnPropertyChanged event in viewModel
public void OnClickCommand(int Id)
{OnPropertyChanged("PropertyA");}
I've actually just put a hack in place to refresh the whole control which will reinitialise and re-fire the converter but any help to solve this would be much appreciated.