I am using mvvm pattern and using integerupdown button in the WPF application.
To invoke command currently I am using ValueChanged trigger as following -
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<i:InvokeCommandAction Command="{Binding PercentChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
This works perfectly fine when user changes value using mouse click on up or down arrow.
Problem is the moment user wants to type in textbox, the event get triggered for every character typed in. Instead I want to allow user to type in numbers and trigger command only on hitting Enter.
Please suggest.
if ValueChanged is triggered on every KeyStroke then your Bindings UpdateSourceTrigger is likely set to default (ValueChanged). Start by setting it to LostFocus. Additionally catch the KeyDown-event with an EventTrigger and check if the key pressed was the Enter-Key.
If its the enter-key then simply call your command.
Edit: if you need a reusable solution for Commit-On-Enter-scenarios have a look at this question.
Found a property - UpdateValueOnEnterKey="True". This will not invoke value changed on every character change, but only on Enterkey press
Related
Please see this EventTrigger:
<ListView Name="ListViewFiles">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding ListViewItemMouseLeftButtonDownCommand}"
CommandParameter="{Binding ElementName=ListViewFiles, Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
So i want to achieve 2 things:
I try to use MouseLeftButtonDown instead of PreviewMouseLeftButtonDown but the event is not fired (why ??).
When the user click and hold the left button i want the event the fire after 500 milliseconds currently i am using timer - any other approach ?
MouseLeftButtonDown probably isn't activating your trigger because of how WPF handles RoutedEvents. When a RoutedEvent gets marked "handled", WPF doesn't call any further event handlers for it.
ListView is almost definitely handling MouseLeftButtonDown internally, probably to change the selected item. Because MouseLeftButtonDown is a bubbling event, that means it gets marked as handled inside the ListView before it gets up the visual tree to your code, so it never arrives.
PreviewMouseLeftButtonDown, on the other hand, is a tunneling event, so it reaches your code before getting into the ListView.
As for the second part of your question, I don't know any better way to trigger code after some time than by using some sort of timer. Also, if you want to trigger it only after they've been holding the button for that amount of time, make sure you handle the PreviewLeftMouseButtonUp event to turn the timer off if they release the button before the time is up.
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 have a UI with a few controls.
Initially when form loads, search button will be disabled, once all
search criteria are given, search button will be enabled
automatically.
On click on search button, I want to call the method
using MVVM pattern and bind the result in grid
XAML:
<Button Name="btnGetDetails" Content="Get Details" Grid.Row="2" Command="{Binding SearchCommand}"/>
What code is required in model, view model and XAML?
Command will be executed only when the button will be clicked on. If you need to do something to the button then you should do it to the Window that contains the button (assuming your button is in a Window). Now if you want to stick with the MVVM pattern then you should not use the Window.OnLoaded, because that would put code in your code behind. One option is to use System.Windows.Interactivity, which you have download seperately. Here is what it will look like:
<Window x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr
-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ...}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Window>
As for what your Model, View and ViewModel should be, I think you should check out some tutorials on the web. There are some very good explanations on how to implement the MVVM pattern. I found this youtube video pretty informative myself:
http://www.youtube.com/watch?v=EpGvqVtSYjs
So some MVVM basics here. You're on the right track, just missing a step. Your Command implementation in your view model should (potentially) accept two inputs: An Action representing the executing code, and a Predicate that returns true/false on whether you can execute the code in the Action block. So, in your view model, define your command along the lines of (note: this is a sample from one of my projects):
this.executeCommand = new RelayCommand(this.OnExecuteClicked, this.OnCanExecuteChanged);
The OnCanExecuteChanged method will return a bool based on whatever criteria you set up. So, if you want the submit button enabled when property A and property B have been properly set up, then return true, else return false. The internal workings of your command implementation will take care of the rest. Do a search for a RelayCommand implementation (if you don't have it already) or a DelegateCommand for further samples.
I'm attempting to use a Command, defined in my view model with EventTriggers as defined in xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
I have changed the control from a Microsoft.Surface.Presentation.Controls.SurfaceSlider-derived control to a regular WPF Button. With the Button, the same ConfirmOrderCommand gets fired if I use the EventName="MouseEnter", but if I use EventName="Click" nothing happens. The XAML for the Button is here.
<Button Name="ConfirmButton"
IsEnabled="{Binding IsEnabled}"
Style="{StaticResource ConfirmButtonStyle}"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ConfirmOrderCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
I want the user to be able to click the button to fire the command. Can I get the Click event to work for a Button, or do I need to look for another event? I've also failed to get MouseLeftButtonUp to work.
Try EventName="Button.Click". Anyways, you can just set the Command Property of the Button itself, and remove the Interaction.Triggers part.
The actual reason the Button.Click would not work, was determined after much pain and finally asking someone on the project after he woke up in the morning.
Our application was stealing almost all of the Button events with FrameworkElement Preview delegates.
public static void RegisterEvents(FrameworkElement parent)
{
parent.PreviewMouseDown += MouseDown;
parent.PreviewMouseUp += MouseUp;
// even more of these
}
The delegates would then use System.Window.Input.TouchDevice to ReportDown() in the case of MouseDown etc. All this time I just thought I didn't know how the standard WPF button usually works. I guess the moral of this story is events don't have to start at the child control and then propagate up to their containers until Handled = true. Preview allows the container to capture the events first.
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);