as mentioned in the title, I would like to create a trigger on a datepicker, or something equivalent. Here is the situation:
<DatePicker SelectedDate="{BindingDateDebut}"/>
<DatePicker SelectedDate="{Binding DateEnd}"/>
No worries about the binding of dates. Now, I'd like when I change my date, it triggers a Command:
LoadMatrice = new RelayCommand(async () =>
{
await GetParametresMatrice();
});
To access the "GetParametresMatrice()" method for example.
I could add the method in the "DateStart" and "DateEnd" set of course, but sometimes both dates change at the same time (during initialization for example) and without "await", my tasks are done at the same time and the output the code gives bad results.
I try with something like :
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding LoadMatrice}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
But it doesn't fire. Any tips ?
Thank you in advance!
The DatePicker has no SelectionChanged event but it has a SelectedDateChanged event that you can try to handle:
<i:EventTrigger EventName="SelectedDateChanged">
Related
I wanted to handle MainWindow's Closing event in one of my ViewModel. This ViewModel belongs to a View which is displayed on top of the MainWindow. I wanted to save values of some properties present in that ViewModel while/before closing of the application.
I am using MvvmCross to implement MVVM pattern. So I tried overriding ViewDisappearing, ViewDisappeared and ViewDestroy methods, but they are only getting called when View get switched, but not when application/window closes.
While searching for this requirement, I could only find this answer: https://social.msdn.microsoft.com/Forums/vstudio/en-US/477e7e74-ccbf-4498-8ab9-ca2f3b836597/how-to-know-when-a-wpf-usercontrol-is-closing?forum=wpf , which is close to my requirement, but needs to be implemented in code-behind.
Can anyone please help me in achieving this in MVVM/MvvmCross in WPF?
I had some experience to implement events by MVVM maybe it can help you.
As I know there is a package on Microsoft.Xaml.Behaviors.Wpf that will help to get the events and execute a command
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{Binding ClosingWindow}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
and if you want to execute a command in other view models you can use a static command
xmlns:local="clr-namespace:App.Views.Windows"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<i:InvokeCommandAction Command="{x:static local:ViewModel.ClosingWindow}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
I'm trying to handle the window closing using a solution similar to this, but the handler in my ViewModel is firing on application start, and not when closing.
XAML:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closing">
<command:EventToCommand Command="{Binding WindowClosing}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModel:
public RelayCommand<System.ComponentModel.CancelEventArgs> WindowClosing
{
get
{
return new RelayCommand<System.ComponentModel.CancelEventArgs>((args) => {});
}
}
The binding is obviously functioning, but it's just firing at exactly the wrong time. I thought the EventName="Closing" is what was supposed to bind to the actual closing event, but it doesn't matter what's contained there. It always fires on loading. What exactly is supposed to link this to the actual window closing event?
I have a mousewheel interactivity trigger on a StackPanel:
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseWheel">
<cmd:EventToCommand Command="{Binding DataContext.PreviousWeekCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
and it works great with the PreviousWeekCommand as follows (snippet):
_previousWeekCommand = new RelayCommand<object>(param => ShiftDays(-7), param => (true));
The PassEventArgsToCommand is there because I'm trying to switch this to a different command that will detect if the user has scrolled up or down. The problem is, after a lot of searching, I still can't figure out how to structure the command to deal with the args. Here's what I have, but it doesn't work:
_scrollWheelCommand = new RelayCommand<MouseEventArgs>(ScrollWheel, can => true);
and then this is the ScrollWheel declaration:
public void ScrollWheel(MouseEventArgs args)
Problem is, I never get to this method when I breakpoint it. I also don't know if I'm routing the arguments in the correct way.
EDIT: Oh, and I get no errors.
Try using MouseWheelEventArgs instead of MouseEventArgs when declaring your RelayCommand. The Parameter type should match the event in order for that to work.
I have a tabbed GUI with each tab containing a Frame. I use the EventToCommand with the SelectionChangedEvent whenever a new TabItem is selected. I do this to update the state of the app. This all works fine - a little bit too fine, the event gets fired too often. Here is my problem:
How can I prevent the event from bubbling up the visual tree by setting the Handled property on the event when using the mvvm light eventToCommand feature?
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<mvvm:EventToCommand
Command="{Binding YourCommand}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
Your command needs to provide parameter from method like RelayCommand . This parameter is event args providing Handled property. More here.
I am having some trouble with an editable ComboBox and the updating of a binding. Currently I have a ComboBox where its UpdateSourceTrigger=LostFocus this is because I need to wait for the user to finish inputting somthing before I decide if the value is a new value (and thus create a new one).
Unfortunately, I have another feature which requires the binding to update when the value has changed aswell. Aka, LostFocus is no good to me in this case. As selecting a new value within the ComboBox it doesn't cause the LostFocus to fire (obviously). So I need to find a way to force update the binding.
I have looked into the SelectionChanged and forcing the update on the binding:
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding ParentConversation.ViewModel.ComboSelectionChanged}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:StoryForgeComboBox}}}"/>
</i:EventTrigger>
And updating the binding in code behind like so:
be = BindingOperations.GetBindingExpression(ele, ComboBox.TextProperty);
if (be != null)
{
be.UpdateSource();
}
Unfortunately I CANNOT update the binding at this point as the value has yet to change. See this stackoverflow topic: ComboBox- SelectionChanged event has old value, not new value
There is a trick where you can possibly use the DropDownClosed event and then update the binding, this works but does not work if you use the Up/Down arrow keys which never opens the ComboBox. Also hooking into KeyUp and KeyDown is too early. The binding cant be updated yet.
So my question is, when is a good time to say "Hey Mr Combo Box, You can update your bindings now".
Cheers.
You can change the SelectionChanged event trigger to LostFocus:
<ComboBox
IsEditable="True"
ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger
EventName="LostFocus">
<i:InvokeCommandAction
Command="{Binding Command}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
When the user types, Text is updated.
When the user types and the ComboBox finds a match in the Items, SelectedItem is changed.
When the user types, the ComboBox does not find a match and a item was previously selected, SelectedItem is set to null.
When the user selects an item, both SelectedItem and Text are updated.
When the user leaves the ComboBox (losing focus), Command is triggered.
When the user has typed text and opens the drop down list, Command is triggered.
EDIT: strangely enough Command is also triggered when it receives focus.
Is this the behavior you want?