I have a DataGrid with the SelectedItem bound to a property in my ViewModel. A Command is executed on the SelectionChanged-Event:
<DataGrid ItemsSource="{Binding MyDataList}" SelectedItem="{Binding MySelectedItem}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding MyCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
In MyCommand under certain circumstances I want to set the DataGrid.SelectedItem to the value it was before the Selection was changed. But the selection highlighting in the DataGrid does not change nevertheless.
Is it possible to prevent ("Handled = true;") the SelectionChanged-Event in the attached Command?
Related
I have a menu item that is configured to execute a command using binding:
<MenuItem Margin="2"
Header="Process something"
Command="{Binding SomethingCommand}"
IsEnabled="{Binding SomethingIsEnabled}">
</MenuItem>
It also configure if this item is enabled or not.
Now, I need to execute the same command when user double click a row in datagrid and only when "SomethingisEnabled" is true.
How to configure datagrid to do that?
setup xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" in xaml
<DataGrid x:Name="dataGrid" ItemsSource="{Binding DataList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding SomethingCommand}" CommandParameter="{Binding ElementName=dataGrid, Path=SelectedItem}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
This will call a relaycommand SomethingCommand and pass the selected item (if any, otherwise null) on the doubleclicked grid.
I'm new to WPF and I don't know why binding from the viewmodel does not execute the specified command.
<CheckBox x:Name="CheckBoxName" Content="MyCheckBox" IsChecked="{Binding Restrictions.MyCheckBox}" Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=CheckBoxName}"/>
When I check the checkbox in the view, MyCommand is executed as expected, but when I set the IsChecked property from the viewmodel using binding, the command is not executed.
Does anyone have any idea why it's happening? How can I execute the command from viewmodel using binding?
Thanks you very much!
As far as I know, the Command is executed on the "Click" event of the base "ButtonBase" class, which is not triggered if you change the IsChecked Property via Binding.
One solution would be to attach a trigger to the Checked and Unchecked event, which triggers your command.
First you need to add the namespace
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
And for your checkbox
<CheckBox x:Name="CheckBoxName"
Content="MyCheckBox"
IsChecked="{Binding Restrictions.MyCheckBox}"
Command="{Binding MyCommand}"
CommandParameter="{Binding ElementName=CheckBoxName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding Path=IsChecked, ElementName=CheckBoxName}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding MyCommand}" CommandParameter="{Binding Path=IsChecked, ElementName=CheckBoxName}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Checkbox>
I have the following situation:
1. I have Window Load event - which gets the SourceItems for a ComboBox
2. ComboBox have EventTrigger for Selection Changed and the following XAML:
<ComboBox x:Name="uxEnvironmentsComboBox"
ItemsSource="{Binding Environments}" Width="90" Margin="0,10,160,0"
HorizontalAlignment="Right"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
IsSynchronizedWithCurrentItem="True" SelectedIndex="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectEnvironment}"
CommandParameter="{Binding Path=SelectedItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
Everything works, the Window Load properly, the List is populated in the ComboBox, but when the default selection is made my <i:EventTrigger EventName="SelectionChanged"> does not trigger and the rest of the application configuration is not triggered unless I make a manual selection change ?!
SelectEnvironment should be a property that you bind to:
<ComboBox x:Name="uxEnvironmentsComboBox"
ItemsSource="{Binding Environments}" Width="90" Margin="0,10,160,0"
SelectedItem="{Binding SelectEnvironment}"
HorizontalAlignment="Right"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
IsSynchronizedWithCurrentItem="True" SelectedIndex="0">
</ComboBox>
You can invoke any command in the setter of this property if you want to:
private Environment _selectEnvironment;
public Environment SelectEnvironment
{
get { return _selectEnvironment; }
set
{
_selectEnvironment = value;
//invoke command
YourCommand.Execute(_selectedEnvironment);
}
}
And if you want to invoke the command or set the property initially, you could for example do this in the constructor of the view model. You don't need to use an InvokeCommandAction.
In one of my views, I have 2 event triggers on a TabControl:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<cmd:EventToCommand Command="{Binding TestCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="TabClosed">
<cmd:EventToCommand Command="{Binding CloseCurrentWorkspaceCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Here is the code for the command bindings:
RelayCommand _t;
public RelayCommand TestCommand { get { return _t ?? (_t = new RelayCommand(foo)); } }
void foo()
{
// This is just to see if the event is firing.
System.Windows.MessageBox.Show("Fired");
}
RelayCommand _closeWorkspaceCommand;
public RelayCommand CloseCurrentWorkspaceCommand
{
get { return _closeWorkspaceCommand ?? (_closeWorkspaceCommand = new RelayCommand(CloseWorkspace)); }
}
void CloseWorkspace()
{
// Workspaces is a ObservableCollection<WorkspaceViewModel>
Workspaces.Remove(SelectedItem);
}
The SelectedItemChanged event never fires when the selected item (or index) is changed. Also changing the event to SelectedIndexChanged has no effect. The TabClosed event fires without a problem. The SelectedIndex and SelectedItem bindings are updating accordingly.
I've checked the output Window and I don't see any binding errors or anything that might suggest the binding is wrong.
How can I start to diagnose why this event won't fire?
Full code of control:
<wpf:TabControlExt Grid.Row="1"
ItemsSource="{Binding Workspaces}"
SelectedItem="{Binding SelectedItem}"
SelectedIndex="{Binding SelectedIndex}">
<wpf:TabControlExt.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header, Mode=TwoWay}"/>
</DataTemplate>
</wpf:TabControlExt.ItemTemplate>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<cmd:EventToCommand Command="{Binding TestCommand}"/>
</i:EventTrigger>
<i:EventTrigger EventName="TabClosed">
<cmd:EventToCommand Command="{Binding CloseCurrentWorkspaceCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</wpf:TabControlExt>
Fixed it.
It turns out I was binding to the wrong event. I should have been binding to SelectionChanged. I only found this out when going through the Triggers pane in Blend. It didn't give me the option to pick SelectedIndexChanged or SelectedItemChanged.
Although in hindsight, SelectionChanged makes more sense since when the item changes, the index changes, and you can't rearrange tabs in the control as far as I know.
So the correct code is:
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand Command="{Binding TestCommand}"/>
</i:EventTrigger>
I have View1, ViewModel1 (which is DataSource for View1) and UserControl (TextBlockComboBoxUC).
View1 contains TextBlockComboBoxUC in XAML like this :
<vwKomp:TextBlockComboBoxUC
ComboBoxItemSource="{Binding Path=ZoznamStatov, Mode=OneWay}"
ComboBoxSelectedValue="{Binding Path=TrvalaAdresa.Stat, Mode=TwoWay}">
</vwKomp:TextBlockComboBoxUC>
TextBlockComboBoxUC contains TextBlock and ComboBox.
How can I call the method from ViewModel1 when ComboBox's SelectionChanged event is raised?
I suppose somehow via delegates, but I have no information about UserControl in ViewModel1.
If you don't mind using the MVVM Light library, I think you can set up a trigger for that event to call the command:
<vwKomp:TextBlockComboBoxUC
ComboBoxItemSource="{Binding Path=ZoznamStatov, Mode=OneWay}"
ComboBoxSelectedValue="{Binding Path=TrvalaAdresa.Stat, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged" >
<cmd:EventToCommand
Command="{Binding YourSelectionChangedCommandHandler}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</vwKomp:TextBlockComboBoxUC>
Where:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
Source: http://www.danharman.net/2011/08/05/binding-wpf-events-to-mvvm-viewmodel-commands/