【问题标题】:EventToCommand in ItemControl in Windows Phone 8Windows Phone 8 中 ItemsControl 中的 EventToCommand
【发布时间】:2013-04-09 09:29:41
【问题描述】:

我不明白为什么我不能在 ItemControl 内的数据模板中调用 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>

这是我试图插入的代码。但是,正如 cmets 所说,它在放入 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>

我如何知道哪个项目被按下了?

【问题讨论】:

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


    【解决方案1】:

    很多答案,但没有一个对我有用。我重新设计了我的解决方案并摆脱了正在工作的 eventtocommand。相反,我制作了带有自定义内容的按钮,使其看起来与我的边框相同。

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

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

    【讨论】:

      【解决方案2】:

      我之前遇到过类似的问题,为我解决的问题是在绑定中引用虚拟机。如果您想接收项目而不是 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。

      希望对你有帮助, 问候。

      【讨论】:

      • 你为 WP8 开发吗?我应该在 StaticResource 中放入什么? Visual Studio 说:资源“定位器”无法解析。
      • 谢谢,我猜你的意思是 Application.Resources 下的 app.xaml,但是 vm 命名空间是什么?我收到以下错误:未定义命名空间前缀“VM”
      • 再次感谢,我引用了我的视图模型,但我的视图模型中没有 ViewModelLocator。之前没有使用过 ViewModelLocator。 ViewModelLocator 在我的 viewmodel 命名空间中不存在。另外,前缀 d 是什么命名空间?
      • 我建议你安装 MVVM Light for VS2012,它包含你需要的所有模板,它会为你创建 ViewModelLocator 和它需要的配置。 mvvmlight.codeplex.com/releases
      • 感谢您的帮助,但您建议在 MVVM Light 中启动一个新项目。我测试了它,仍然是同样的问题。我将在这里发布我自己的问题解决方案。为帮助竖起大拇指!
      【解决方案3】:

      我认为这与您在数据模板中的绑定有关。视图是如何创建的?我认为该命令是 viewModel 的属性,而不是 GroupRow1,它是您的项目控件的集合。您需要绑定到 ViewModel 中的命令。因此,如果您的视图是用户控件,则以下内容应该有效。 (如果它是另一种类型,则更改祖先类型)

       <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}"/>
      

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

      我个人会在我的视图模型中拥有 SelectedItem 属性,该属性可以作为 ItemSelectCommand 中的对象进行访问

      希望这会有所帮助。

      【讨论】:

      • 谢谢,现在我看到了问题所在。但是,此解决方案不适用于 Silverlight,而仅适用于 WPF。 Silverlight 不支持 FindAncestor。
      【解决方案4】:

      答案很明显。在 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>
      

      【讨论】:

      • 感谢您的回答,但这在 Silverlight 和 WP 中不起作用,仅在 WPF 中起作用。 Silverlight 不支持 FindAncestor
      • 我的解决方案没有实现查找祖先。评论前仔细看
      • 对不起。但我指的是一般的祖先。 Windows Phone 不适用于祖先,在这种情况下是 AncestorType。
      • 嗯,是的,windows phone 是 silverlight 的一种子集。 silverlight 5 支持这个我不知道windowa 手机虽然
      • 好的,在为 windows phone 构建时,我收到以下错误:“在类型 'RelativeSource' 中找不到属性 'AncestorType'”。我还读到 WP 不支持这个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      相关资源
      最近更新 更多