如何为整个Interaction.Triggers
设置ListBoxItem
?我见过this question,但答案并未使用互动子。甚至有可能吗?
目前我有ListBox
这样的人:
<ListBox ItemsSource="{Binding CharactersList}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="Focusable" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Red">
<TextBlock x:Name="CharacterTextBlock" Text="{Binding}" Width="20" Height="20" TextAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CharacterClick}"
CommandParameter="{Binding}" />
</i:EventTrigger>
<i:EventTrigger EventName="TouchUp">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CharacterClick}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
即使我单击红色Border
以外的位置,我也想触发特定项目的事件触发器。
答案 0 :(得分:1)
最简单的方法是在视图的代码背后处理ListBoxItem
的事件并从那里调用命令:
private void ListBoxItem_MouseUp(object sender, MouseButtonEventArgs e) => InvokeCommand(sender);
private void ListBoxItem_TouchUp(object sender, TouchEventArgs e) => InvokeCommand(sender);
private void InvokeCommand(object sender)
{
ListBoxItem lbi = sender as ListBoxItem;
var vm = DataContext as YourViewModel;
if (vm != null)
vm.CharacterClick.Execute(lbi.DataContext);
}
XAML:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="Focusable" Value="False" />
<EventSetter Event="MouseUp" Handler="ListBoxItem_MouseUp" />
<EventSetter Event="TouchUp" Handler="ListBoxItem_TouchUp" />
</Style>
</ListBox.ItemContainerStyle>
不,这不会破坏MVVM模式,因为您仍在从完全相同的视图调用完全相同的命令。
另一种选择是使用封装上述功能的attached behaviour并设置附加属性,如下所示:
<Style TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<Setter Property="Focusable" Value="False" />
<Setter Property="local:YourBehavior.MouseUpCommmand" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CharacterClick}" />
<Setter Property="local:YourBehavior.MouseUpCommmandParameter" Value="{Binding}" />
<!-- ... -->
</Style>
如果您打算在多个不同的视图中重用此功能,则这样做可能很有用。否则,您可以使用代码隐藏选项。 MVVM并不是要从视图中消除代码。这是关于关注点分离的,仅仅是因为您实际上可以在XAML中做某事,但这并不意味着您总是应该这样做。