考虑这个xaml:
<ListView ItemsSource="{Binding Items}" PreviewMouseLeftButtonDown="{Binding CheckItemCommand}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.Header>
<CheckBox IsThreeState="True"
IsChecked="{Binding IsSelectAll, Mode=TwoWay}"
Command="{Binding CheckAllCommand}">
</CheckBox>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate DataType="x:MyObject">
<Grid>
<TextBlock Text="{Binding LoadingState}"/>
<CheckBox IsThreeState="False"
IsChecked="{Binding IsSelected, Mode=TwoWay}"
Command="{Binding CheckItemCommand}">
</CheckBox>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="{Binding MyObject.Header_Name}"
DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="{Binding MyObject.Header_CreationDate}"
DisplayMemberBinding="{Binding CreationDate}" />
<GridViewColumn Header="{Binding MyObject.Header_NumberOfStuff1}"
DisplayMemberBinding="{Binding stuff1}"/>
<GridViewColumn Header="{Binding MyObject.Header_NumberOfStuff2}"
DisplayMemberBinding="{Binding stuff2}"/>
</GridView>
</ListView.View>
</ListView>
当我点击行上的任何地方时,我想调用CheckItemCommand,它已经绑定在行复选框上。
如何使用
指定单击的行PreviewMouseLeftButtonDown="{Binding CheckItemCommand}"
答案 0 :(得分:1)
您可以使用互动触发器:
<ListView ItemsSource="{Binding Items}"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseLeftButtonDown" >
<i:InvokeCommandAction Command="{Binding CheckItemCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
...
</ListView>
EventTrigger
在System.Windows.Interactivity.dll
中定义,它是Blend SDK的一部分:Visual Studio 2017 - What happened to Expression interactions?
有关详细信息,请参阅以下博客文章:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/。
答案 1 :(得分:0)
我会使用鼠标绑定而不是事件。 您使用样式申请:
当您单击某行时,您将使其成为所选项目,以便您可以使用该项目。或许不是,因为我看到你已经有一些选择了。
<Style TargetType="ListViewItem">
<Setter Property="local:AddToInputBinding.Binding">
<Setter.Value>
<MouseBinding Gesture="LeftClick" Command="{Binding YourCommand}" />
</Setter.Value>
</Setter>
您用于命令的代码可以使用绑定到selecteditem的属性。 如果这不适合,那么您可以使用命令参数来提供单击的项目。 我认为这看起来像:
CommandParameter="{Binding}"
这将为您提供行所拥有的整个对象,因为它是datacontext - 来自Items的项目。 如果你的命令不在列表视图中的每个项目的任何对象中,那么就会出现一些复杂问题。 你需要找到listview的datacontext(而不是你的鼠标绑定将在“in”中结束的行)。 使用relativesource做那件事。 这方面看起来像:
Command="{Binding DataContext.YourCommand,
RelativeSource={RelativeSource
AncestorType={x:Type ListView}}}"
我试图解释所涉及的原则,而不仅仅是为你做这件事。
如果你是命令和参数的新手,那么mvvmlight非常好,这篇关于relaycommand的文章可能会澄清:
Guid.NewGuid().ToString()
答案 2 :(得分:0)
我找到了有用的东西。我不太了解这个解决方案,但它工作正常,理解非常简单,并且可以用非常好的代码完成(=&gt; KISS原则)。
要有一个正确的“OnRowClick =&gt; DoStuff()”行为,我拦截所有左键单击,如果源是正确的类型,我调用Command_Execute()方法。
代码:
public MyContainer()
{
InitializeComponent();
this.PreviewMouseDown += MyContainer_PreviewMouseDown;
}
private void MyContainer_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var source = e.OriginalSource as FrameworkElement;
var dataContext = source?.DataContext;
if(dataContext.GetType() == typeof(ProperViewModel))
{
((ProperViewModel)dataContext).Command_Execute();
}
}
我很难过没有原生的方式通过纯粹的Command模式来做到这一点......
如果某人有更好的方法可以做到这一点,请随意提出另一个更优雅的答案