Trying to bind the click or checked event on a WPF chekbox to a command in my viewmodel, but im unsure on the technique and the event names, can anyone point me in the right direction?
For now the code compiles but the the trigger does not call the FooCommand
<CheckBox IsChecked="{Binding PartData.ReportIncluded, Mode=TwoWay}"
VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown" >
<i:InvokeCommandAction Command="{Binding FooCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
Looks like you're missing the "On" prefix of your event, i.e. OnMouseLeftButtonDown or OnPreviewMouseLeftButtonDown
Related
I have a user control that use another user control. The child user control has a combobox and the click event works because i can open the combobox, but the double click it doesn't work.
My code is this:
Main user control:
<StackPanel>
<views:ucMyChildUserControl/>
</StackPanel>
My child user control:
<StackPanelOrientation="Horizontal">
<StackPanel Orientation="Vertical">
<Label Content="Content" Style="{StaticResource LabelDefault}"/>
<ComboBox Name="cmbMyCombobox"/>
</StackPanel>
<!--More related controls-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding MyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</StackPanel>
But I have realized that if the comand of mouse double click is set in the parent user control, it works:
<views:ucChildUserControl>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding MyCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</views:ucChildUserControl>
So I guess the problem is about the handling of the event, but I don't know how to catch it in the child user control.
Thanks.
The issue is that the MouseDoubleClick event and the PreviewMouseDoubleClick are defined on Control. Since UserControl is a derivative of Control, the event is available and can be handled. However, StackPanel is not a derivative of Control so the event is not available, therefore the trigger does not work.
There are workarounds to this in code-behind that you can eventually turn into a behavior for MVVM, but simple workarounds like using input bindings on the left mouse click action only work on some elements, as others like ComboBox will already handle it and then the input bindings are not triggered.
<StackPanel Orientation="Horizontal">
<StackPanel.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding MyCommand}"/>
</StackPanel.InputBindings>
<StackPanel Orientation="Vertical">
<Label Content="Content"/>
<ComboBox Name="cmbMyCombobox"/>
</StackPanel>
<!--More related controls-->
</StackPanel>
The most simple solution without creating additional code is to wrap the StackPanel in a control that is a derivative of Control, e.g. a ContentControl, like this.
<ContentControl>
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<Label Content="Content"/>
<ComboBox Name="cmbMyCombobox"/>
</StackPanel>
<!--More related controls-->
</StackPanel>
<b:Interaction.Triggers>
<b:EventTrigger EventName="MouseDoubleClick">
<b:InvokeCommandAction Command="{Binding MyCommand}" />
</b:EventTrigger>
</b:Interaction.Triggers>
</ContentControl>
I'm using the DoubleUpDown UserControl from the Extended WPF Toolkit in my current project. Now I have to bind a RelayCommand to the DoubleClick event of that DoubleUpDown, but it is not working. I've assigned that DoubleClick to all kinds of different UserControls so far and usually it was working fine or sometimes I had to wrap it into an empty UserControl-Element which would then hold the CommandBinding, but so far I always got it working.
This is what I tried so far:
<UserControl Grid.Row="7"
Grid.Column="0">
<xctk:DoubleUpDown Value="{Binding EditableDevice.SelectedLoadReceptor.DecimalPlaces,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay, FallbackValue='1'}"
FormatString="F0"
Minimum="0"
Maximum="10">
<xctk:DoubleUpDown.InputBindings>
<MouseBinding Command="{Binding EditDeviceCommand}"
Gesture="LeftDoubleClick" />
</xctk:DoubleUpDown.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LeftDoubleClick">
<cmd:EventToCommand Command="{Binding EditDeviceCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</xctk:DoubleUpDown>
<UserControl.InputBindings>
<MouseBinding Command="{Binding EditDeviceCommand}"
Gesture="LeftDoubleClick" />
</UserControl.InputBindings>
</UserControl>
I'm usually fine with using the InputBindings, but not with the DoubleUpDown...
I wonder what is causing the issue. Does anyone here have an idea or a workaround?
Regards
Ralf
Hmm, still couldn't figure out what is wrong here. In the meantime I'll just use CodeBehind where ever possible by using the regular MouseDoubleClick-Event.
I have an editable ComboBox.
<ComboBox IsEditable="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}"/>
</i:EventTrigger>
<i:EventTrigger EventName="TextBoxBase.TextChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
I use GalaSoft.MvvmLight.Command.EventToCommand to bind the SelectionChanged event.
I also would like to bind the TextChanged event, but it is a little bit tricky:
This event is only accessible by the ComboBox TextBoxBase property, and I can't find the proper way to bind this event.
You can see one of my unsuccessful attempt: SelectionChanged binding works fine, but TextChanged binding does not.
I also tried this syntax:
<ComboBox IsEditable="True">
<TextBoxBase>
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBoxBase>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
But this won't even compile. I get an error "Type that can be instantiated expected" on the TextBoxBase tag.
Any idea ?
I know, very late response... but I hope it will help someone.
The problem here is that the EventTrigger class in Microsoft.Expression.Interactivity.dll uses reflection to find the event by the value of the EventName property and this won't work for attached events like TextBoxBase.TextChanged.
One option, which I use, is to implement your own custom EventTrigger class as described here and use this one instead of EventTrigger (the link there to CommandAction implementation is broken, but I managed to get it using internet archive).
Another option, which I don't like because it's not classic MVVM Command use, is to bind the Text property of the ComboBox to a property in the ViewModel and invoke the command from the ViewModel code on the setter, like this:
<ComboBox IsEditable="True"
Text="{Binding Text, Mode=TwoWay}" />
And in the ViewModel:
private string text;
public string Text
{
get { return text; }
set
{
text = value;
OnPropertyChanged("Text");
if(CritereChangedCommand.CanExecute())
CritereChangedCommand.Execute();//call your command here
}
}
I have found a way to work around the problem:
I create an invisible TextBox, bound to the ComboBox, and I bind the command on the TextChanged event of the TextBox.
It's not pretty, but it works...
<ComboBox Name="CbRubrique" IsEditable="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<TextBox Text="{Binding ElementName=CbRubrique, Path=Text, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<cmd:EventToCommand Command="{Binding CritereChangedCommand, Mode=OneWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
I am using Silverlight 5 and in a view I have a Button that, when clicked, loads a particular state. This is done using an EventTrigger and the GoToStateAction markup like so:
<Button x:Name="..." Content="...">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="MyState"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
The above works swimmingly, but if I move the Button into a DataGridTemplateColumn it no longer works. Specifically, the app compiles without error and the DataGrid shows the button in a column, but when I click the button the state is not transitioned to.
<data:DataGrid ...>
<data:DataGrid.Columns>
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="..." Content="...">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:GoToStateAction StateName="MyState"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
</data:DataGrid.Columns>
</data:DataGrid>
Is it not possible to have EventTriggers in a DataGridTemplateColumn? Or do I need to declare them using alternate syntax?
Thanks
The GoToStateAction reference states that, if no target is specified, it will walk up the visual tree and apply the state change on the first element it finds that defines states. In your second case, I believe that some elements of the DataGrid visual tree (cells, rows, etc) may be taken in account before your usercontrol, thus the behavior you've seen.
Since you are using Silverlight 5, you can try to set the TargetObject property of the action to your desired control, using a binding with a relative source looking of a ancestor of the type of UserControl.
<ei:GoToStateAction StateName="MyState" TargetObject="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>
Using silverlight, we are looking to move the focus to a textbox.
How do you use mvvm-light to trigger gotfocus?
The view contains:
<TextBox Margin="4,4,0,0" Text="{Binding Path=SearchOID, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<cmd:EventToCommand Command="{Binding GotFocusCommand, Mode=TwoWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
How should the ViewModel look?
How do you trigger this from the ViewModel?
Ended up using a TriggerAction, very similar to:
http://www.codeproject.com/Articles/42988/Silverlight-Behaviors-and-Triggers-Making-a-Trigge.aspx