Windows Phone 8中ItemsControl中的EventToCommand

时间:2013-04-09 09:29:41

标签: silverlight windows-phone-8 mvvm-light datatemplate eventtocommand

我无法理解为什么我无法在ItemControl中的datatemplate中调用eventToCommand。根据这个post我应该在dataTemplate中实现它,但是从不调用该命令。这是我试图在我的代码中插入的eventToCommand。

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

这就是我试图将其付诸实践的代码。但是,正如评论所说,在放​​入dataTemplete时永远不会调用它。问题不在于viewModel,该命令在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>

如何找出按下了哪个项目?

4 个答案:

答案 0 :(得分:2)

许多答案,但它们都不适合我。我重新设计了我的解决方案并摆脱了那些工作正常的事件。相反,我使用自定义内容制作的按钮看起来与我的边框相同。

更简单的代码和更好的解决方案。

<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>

答案 1 :(得分:1)

之前我遇到过类似的问题,为我解决的问题是在绑定中引用了VM。如果您想要接收项目而不是EventArgs

,请尝试将PassEventArgsToCommand设置为false
<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>

编辑 - 如果你正在使用MVVM Light,在app.xml你应该有类似的东西:

xmlns:vm="clr-namespace:PhoneApplication.ViewModel(ViewModelLocator所在的命名空间)

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

您告诉绑定在ViewModelLocator中查找特定VM。

希望它有所帮助, 问候。

答案 2 :(得分:0)

我认为这与您在数据模板中的绑定有关。视图是如何创建的?我认为该命令是viewModel的属性,而不是GroupRow1属性,它是item控件的集合。您需要绑定到ViewModel中的命令。因此,如果您的视图是用户控件,则以下内容应该有效。 (如果它的另一种类型然后更改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}"/>

命令参数添加了文本块的名称,例如,您可以将其更改为文本块的任何属性。

我个人在我的viewmodel中有SelectedItem属性,可以从ItemSelectCommand作为对象访问

希望这有帮助。

答案 3 :(得分:0)

答案非常明显。在ItemsPanelTemplate中,您的绑定源仍然是ViewModel,您的命令将保留在ViewModel中。但是在DataTemplate中,您正在迭代GroupRow1项目,而您的绑定源是单独的项目。如果要在那里使用命令,则必须从示例中的相对源绑定:

<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>