ListView项目单击事件MVVM

时间:2017-02-10 04:06:13

标签: c# wpf listview eventtrigger

我有一个带有ListView的MenuItem。我想说的是:当我点击ListView项目时,会触发一些命令。这是我的代码:

<MenuItem Header="?">
<ListView ItemsSource="{Binding CommentTemplateList}" BorderThickness="0" SelectedItem="{Binding SelectedCommentTemplate, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding PasteTemplate}"
CommandParameter="{Binding SelectedCommentTemplate}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Caption}" ToolTip="{Binding Description}" HorizontalAlignment="Center"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</MenuItem>

Everithing没问题,但只有在选择更改时才会触发命令PasteTemplate,我每次点击项目时都需要触发它。如果我将列表中的EventName更改为一个(https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.aspx),例如MouseDown,则命令根本不会触发。

3 个答案:

答案 0 :(得分:0)

您可以按照此处的建议处理ListViewItem预览 MouseDown事件:

WPF MVVM Light Multiple ListBoxItems bound to same object

<ListView ...>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnMouseLeftButtonDown"/>
        </Style>
    </ListView.ItemContainerStyle>
    ..
</ListView>

如果您不想从代码隐藏中调用视图模型的命令,则可以在附加行为中包含相同的功能:https://www.codeproject.com/articles/28959/introduction-to-attached-behaviors-in-wpf

以上链接中有更多信息示例。

答案 1 :(得分:0)

要实现这一点,在尊重MVVM架构的同时,最好的方法是将特定行为添加到xaml代码中,如下所示;

 <ListView  x:Name="ListView"
                            ItemsSource="{x:Bind ViewModel.SampleItems, Mode=OneWay}"
                            SelectedItem="{x:Bind ViewModel.SelectedItem, Mode=OneWay}"
                            IsItemClickEnabled="True">
                        <i:Interaction.Behaviors>
                            <ic:EventTriggerBehavior EventName="ItemClick">
                                <ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemClickCommand}" />
                            </ic:EventTriggerBehavior>
                        </i:Interaction.Behaviors>

                    </ListView>

在View Model中,在声明IComand属性后,如下所示

public ICommand ItemClickCommand
    {
        get
        {
            if (_itemClickCommand == null)
            {
                _itemClickCommand = new RelayCommand<ItemClickEventArgs>(OnItemClick);
            }

            return _itemClickCommand;
        }
    }

定义命令,就好像您在后面的代码中处理事件一样;

private void OnItemClick(ItemClickEventArgs args)
{ListDataItem item = args?.ClickedItem as ListDataItem; //DO what ever you want with the Item you selected in the click}

注意:RelayCommand用于使用MVVMLight Framework处理命令。

答案 2 :(得分:-1)

如果您想使用'SelectionChanged',您可以在代码后重置选择。只需在PasteTemplate

上添加它即可
if(((ListView)sender).SelectedIndex == -1)return;
//your code
((ListView)sender).SelectedIndex = -1;

因此,在您的代码之后,ListView没有选定的元素。因此,如果再次单击它,则会再次更改选择并再次触发代码。

注意:您也可以使用MouseDown,但这有点棘手。例如,如果用户点击了您的任何商品,而不是像this那样点击ListView中的其他商品,则会再次点击您当前的选择。