So I am using GalaSoft's EventToCommand for binding my View's Loaded event to my command in my ViewModel. The binding is working great but my Command is never being executed. The only way I have been able to get this to work is to handle the Loaded event in my View's code behind and then cast my DataContent to my VM and tell it to run my code (which the command is trying to do). Obviously this isnt very nice when trying to do it all MVVM like. FYI I did try the MouseEnter event and that worked great so that makes me think its a timing issue. Also, my View is a user control.
View:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<cmd:EventToCommand PassEventArgsToCommand="False" Command="{Binding Path=DownloadDataCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel:
public RelayCommand DownloadDataCommand
{
get { return new RelayCommand(() => DownloadDataAsync()); }
}
Ive tried calling simple methods that do pretty much nothing and my relay command is still not invoked. So I doubt its the action within the RelayCommand. Does anyone see what I am doing wrong?
Related
in my window I want to use this code
<i:Interaction.Triggers>
<i:EventTrigger EventName="SourceInitialized">
<command:EventToCommand Command="{x:Static wpf:Window.InitializeWindowProcessHookCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
to hook the SourceInitialized event to a command on my so-called Window class.
I am using MvvMLight EventToCommand and if it works perfectly if I use the Loaded event instead of the SourceInitialized, so we can assume that the command and further logic is working.
Additionally, using the event with code behind works, but I am looking for a solution using EventTriggers (if possible).
When looking up a possible solution, I stumbled across a topic on MSDN, which is about this exact topic, and the OP points states that he successfully bound to the Loaded event, but cannot get binding to the SourceInitialized to work
[and I] want to write a similar one for windows source initialized event, but find that Window.SourceInitializedEvent is not exposed
Is there any possible solution to that?
Many thanks in regard
The SourceInitialized event fires before your trigger has a chance to invoke the command so this won't work.
Also, it doesn't make much sense to fire the command using an EventTrigger that is defined in the XAML markup just for the sake of not having to do it from the code-behind of the same view. MVVM is not about eliminating view-related code from the views and it doesn't break the pattern to invoke the command from the code-behind of the same view as your XAML markup is defined in.
So invoke the command from an event handler in the code-behind or subscribe to another event.
As you have already noticed, there is no way to handle the SourceInitialized event of a window using an EventTrigger that is defined in the XAML markup of the same window.
In my MVVM application a have a button in a view.
When I press a button I want the run some method in the view, and also some method in the view model.
I connected come command to my button, so the command can run some method in the view model. But how can I run some method in view also?
I tried to connect a click event also, but it does not work.
What is the best way to run functions from view and viewmodel also.
Thanks,
You can do this entirely in XAML with interaction triggers:
<Button Content="Do Something" Click="OnClickHandler"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd ="http://www.galasoft.ch/mvvmlight">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding Path=ViewModelCommand1}" />
<cmd:EventToCommand Command="{Binding Path=ViewModelCommand2}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
In this case both the Window handler and each of the two viewmodel commands get invoked. If the handler sets e.Handled to true the viewmodel commands don't get called. If you set PassEventArgsToCommand="True" in the cmd:EventToCommand then you can specify a handler that accepts the args; setting Handled to true in the first viewmodel handler won't stop the second one being called but you can still check the value in the second handler manually.
Now, that said I would strongly encourage you to re-evaluate your architecture. Calling code-behind is not MVVM, and in over 7 years of doing this on a daily basis I have yet to see a single case where it was actually needed.
on the Click event, Execute command.
private void btnClick(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
btn.Command.Execute(btn.CommandParameter);
}
I would highly question your decision to "run both view and viewmodel method on button click". To me, it seems that what you want is that button runs a viewmodel command which in turn causes some change in view. What if for example it was possible to execute the method not through UI but from somewhere else in the application. Shouldn't the view change also?
For that I recommend creating an interface I[something]View, that the view will implement and which the view model have reference to. Then, the viewmodel can call the method on the interface which will do what you are expecting on the button click.
I am searching for a way how to realize a window close command, which is usable in the window's CommandBindings and by other sources, for example a button. I am working with MVVM. So far, I only found solutions that were either meant for use by CommandBindings or with a simple Command featured inside the MVVM. I need to have one central handler for this.
Thanks in advance!
Simply use EventToCommand.
ViewModel:
public ICommand WindowClosing
{
get
{
return new RelayCommand<CancelEventArgs>(
(args) =>{
});
}
}
and in XAML:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<command:EventToCommand Command="{Binding WindowClosing}" />
</i:EventTrigger>
</i:Interaction.Triggers>
Does using MVVM model in WPF restricts the programmer from writing code behind? Avoiding Code behind results in lot of complications but on the other hand coupling rises as an issue. So what is better?
The MVVM model does NOT restrict you from writing code behind.
What it does promote is that the View should only be dependent on the ViewModel (and the ViewModel on the Model)
So if you write code behind that is actually implementing the ViewModel you are creating a dependency from the ViewModel to the View.
Code behind that ONLY does View related things is OK
The thing you are losing when using code behind is the easy (unit)testing of that code.
EDIT
A common expression in MVVM-world is "XAML only". As much as I like a short, snappy statement it tends to divert from the actual problem MVVM is trying to solve and how it tries to solve it.
As long as you stick to making the View dependent on the ViewModel and the ViewModel on the Model AND strive for (unit)testability you are on the right track.
EDIT 2
In the View handling an event should only do two things: change the View itself or notify the ViewModel using a binding that something has changed. Notifying the VIEW of a change in the ViewModel should be done by implementing INotifyPropertyChanged on the ViewModel.
In a similar way the ViewModel can respond to events in the View by binding ViewModel Commands to the View.
A WPF Button has a Command property that can be used. It is executed when the button is clicked.
If a control has no Command property or you want to execute a command when a different event is raised all you have to do is turn the event into the execution of an ICommand.
Microsoft already provided an implementation of that in the Blend SDK. From this article:
... xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity..."
<Slider
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}"
CommandParameter="{Binding Text, ElementName=textBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Slider>
And a discussion about commands versus event triggers
I'm just starting with MVVM light, but so far it allowed me to solve some of my issues. Infortunately I'm struggling with relatively sime issues in Silverlight.
Let's assume the following button with EventToCommand:
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding UpdateAccountsCommand, Mode=OneWay}" CommandParameter="{Binding SelectedIndex, ElementName=lstLedgers}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
How to assign this code to SelectedIndexChanged event?
Futher issue - how to assign a command in C# code? The problem is as follows: I'm developing Windows Phone 7 app. Application Bar needs to be initiated in C# (as far as I know there is no xaml code for application bar at this stage). As a result I have no idea how to bind a command to a application bat button in from c#, now xaml.
Thanks in advance your your help.
How to assign this code to SelectedIndexChanged event
The event name is in the trigger's initial xaml line. The EventName is what triggers something to happen. You'll need to make sure that you have this trigger on an object with a SelectedIndexChanged event. Button doesn't have that event.
...
<i:EventTrigger EventName="SelectedIndexChanged">
...
If you are breaking mvvm for the application bar, I don't know why you'd want to create a trigger. You might as well go the direct route by accessing the events you want directly. You can do it, don't get me wrong... just this code is a lot cleaner:
ApplicationBarButton.Click += new RoutedEventHandler(OnApplicationBarButton_Click);