I am using WPF MVVM design pattern. I need to raise a PreviewKeyDown event from a textbox that was created using an ItemsControl. I am able to add items to the collection SourceCollection, but unable to trigger the PreviewKeyDown event using interaction triggers. Any ideas on what I might be missing in the xaml is appreciated :) Here's my code:
MainWindow.xaml
<Grid>
<ItemsControl ItemsSource="{Binding SourceCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding CollectionText}" Foreground="{Binding Path=ForegroundColor}"
FontSize="16" FontWeight="ExtraBold" FontFamily="Courier New">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<i:InvokeCommandAction Command="{Binding KeyDownAction}"></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
MainWindowViewModel.cs
public class MainWindowViewModel
{
MainWindowModel model = new MainWindowModel();
private ObservableCollection<MainWindowModel> _SourceCollection;
public ObservableCollection<MainWindowModel> SourceCollection
{
get { return _SourceCollection; }
set { _SourceCollection = value; }
}
public MainWindowViewModel()
{
SourceCollection = new ObservableCollection<MainWindowModel>();
for (int i = 0; i < 4; i++)
{
model = new MainWindowModel();
model.CollectionText = "This is line " + i;
if (i % 2 == 0)
{ model.ForegroundColor = Brushes.Blue; }
else
{ model.ForegroundColor = Brushes.Green; }
SourceCollection.Add(model);
}
}
public RelayCommand<KeyEventArgs> KeyDownAction
{
get { return new RelayCommand<KeyEventArgs>(KeyDownMethod); }
}
private void KeyDownMethod(KeyEventArgs e)
{
//some code here
}
}
the "Binding" for your Command in the "InvokeCommandAction" is incorrect. It is NOT on an individual collection item, but at the ViewModel level. Change it to:
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource AncestorType=Window},
Path=DataContext.KeyDownAction}">
</i:InvokeCommandAction>
This way you're pointing to the command defined in the ViewModel.