0

I cannot understand why I cant call eventToCommand in my datatemplate inside ItemControl. According to this post I should implement it in the dataTemplate, but the command is never invoked. This is the eventToCommand im trying to insert in my code.

<i:Interaction.Triggers>
   <i:EventTrigger EventName="Tap">
        <cmd:EventToCommand Command="{Binding ItemSelectedCommand, Mode=OneWay}"
               PassEventArgsToCommand="True" />
   </i:EventTrigger>
</i:Interaction.Triggers>

And this is the code im trying to instert it to. However, as the comments say, it is never invoked when put in the dataTemplete. The problem is not the viewModel, the command works in the panelTemplate.

<ItemsControl ItemsSource="{Binding GroupRow1}" >
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
             <!-- COMMAND WORKS HERE, but cannot locate which item has been pressed -->
         </StackPanel>
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
   <ItemsControl.ItemTemplate>
       <DataTemplate>
           <Border Background="#FF1756C3" Height="173" Width="173" Margin="12,0,0,0" >
                <!-- COMMAND DOES NOT WORK HERE?!?! -->
                <StackPanel> 
                   <TextBlock Text="{Binding LineOne}" /> <!-- These bindings work -->
                   <TextBlock Text="{Binding LineTwo}" />
                </StackPanel>
           </Border>
       </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

How do I find out which Item has been pressed?

Community
  • 1
  • 1
Zeezer
  • 1,503
  • 2
  • 18
  • 33

4 Answers4

2

Many answers, but none of them worked for me. I redesigned my solution and got rid of the eventtocommand which wasent working. Instead I made buttons with custom content to look the same as my border.

Simpler code and a better solution.

<ItemsControl ItemsSource="{Binding GroupRow1}" >
<ItemsControl.ItemsPanel>
  <ItemsPanelTemplate>
     <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
     </StackPanel>
  </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
   <DataTemplate>
      <Button CommandParameter="{Binding LineOne}" Height="195" Width="195" Margin="0,0,-10,0" Click="Button_Click_2" Background="#FF1756C3">
            <StackPanel> 
               <TextBlock Text="{Binding LineOne}" /> 
               <TextBlock Text="{Binding LineTwo}" />
            </StackPanel>
       </Button>
   </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Zeezer
  • 1,503
  • 2
  • 18
  • 33
1

I had a similar problem before, what solved it for me was referencing the VM in the binding. Try to set PassEventArgsToCommand to false if you want to receive the item instead of the EventArgs

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Tap">                                    
         <cmd:EventToCommand PassEventArgsToCommand="False" 
                             CommandParameter="{Binding}" 
                             Command="{Binding Path=VM_Name_Here.Command_Name_Here, Source={StaticResource Locator}}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

Edit- If you are using MVVM Light, in the app.xml you should have something like:

xmlns:vm="clr-namespace:PhoneApplication.ViewModel (namespace where your ViewModelLocator is under)

   <vm:ViewModelLocator x:Key="Locator"
                             d:IsDataSource="true" />

You are telling the binding to look in the ViewModelLocator for a particular VM.

Hope it helps, Regards.

D.Rosado
  • 5,634
  • 3
  • 36
  • 56
  • Do you develop for WP8? What should I put in StaticResource? Visual studio says: the resource "Locator" could not be resolved. – Zeezer Apr 19 '13 at 13:28
  • Thanks, I guess you meant app.xaml under Application.Resources, but what is the vm namespace? I get the following error: The namespace prefix "VM" is not defined – Zeezer Apr 22 '13 at 11:23
  • Thanks again, ive referenced my viewmodel but I dont have a ViewModelLocator in my ViewModels. Havent used ViewModelLocator before. ViewModelLocator does not exist in my viewmodel namespace. Also, what namespace is prefix d? – Zeezer Apr 22 '13 at 12:25
  • I'd recommend you to install MVVM Light for VS2012, it contains all the templates you need, it'll create for you the ViewModelLocator and the configuration it needs. http://mvvmlight.codeplex.com/releases – D.Rosado Apr 22 '13 at 13:05
  • Thanks for the help, but what you recommend is to start a new project in MVVM Light. I tested it, and still the same problem. I'll post my own solution to the problem here. Thumbs up for helping! – Zeezer Apr 24 '13 at 08:52
0

I think it has to do with your binding in the data template. How is the view created? I think the command is a property of the viewModel, not GroupRow1 which is the collection for your items control. You need to bind to the command in your ViewModel. SO if your view is a usercontrol, the following should work. (if its of another type then change the ancestortype)

 <cmd:EventToCommand Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.ItemSelectedCommand}"
    CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBlock}},Path=Name}"/>

The command parameter adds the name of the textblock for example, you could change that to any property of the textblock.

I would personally have SelectedItem property in my viewmodel that can be accesses as an object from the ItemSelectCommand

Hope this helps.

J King
  • 4,108
  • 10
  • 53
  • 103
  • Thanks, now I see the problem. However, this solution does not work in silverlight, but only WPF. Silverlight does not support FindAncestor. – Zeezer Apr 15 '13 at 08:03
0

The answer is pretty obvious. In ItemsPanelTemplate your binding source is still the ViewModel and your command stays at your ViewModel. But in DataTemplate you are iterating over GroupRow1 items and your binding source is individual item. If you want to use your command there, you have to bind from the relative source in example:

<i:Interaction.Triggers>
 <i:EventTrigger EventName="Tap">
    <cmd:EventToCommand Command="{Binding ViewModel.ItemSelectedCommand, RelativeSource={RelativeSource AncestorType=UserControl}, Mode=OneWay}"
           PassEventArgsToCommand="True" />
 </i:EventTrigger>
</i:Interaction.Triggers>
Xelom
  • 1,615
  • 1
  • 13
  • 23
  • Thanks for the answer but this does not work in silverlight and WP, only in WPF. Silverlight does not support FindAncestor – Zeezer Apr 15 '13 at 08:07
  • My solution is not implementing find ancestor. Look carefully before you comment – Xelom Apr 15 '13 at 14:53
  • Sorry. But I meant Ancestor in general. Windows Phone does not work with ancestor, and in this case AncestorType. – Zeezer Apr 15 '13 at 15:18
  • Hmm yes windows phone is kind of subset of silverlight. silverlight 5 supports this i dont know windowa phone though – Xelom Apr 15 '13 at 15:29
  • Ok, when building for windows phone I get the following error: "The property 'AncestorType' was not found in type 'RelativeSource'". I´ve also read that WP does not support this. – Zeezer Apr 15 '13 at 19:04