【问题标题】:ListView item click event MVVMListView 项目点击事件 MVVM
【发布时间】:2017-06-28 07:50:21
【问题描述】:

我有一个带有 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"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
   </ListView>
</MenuItem>

一切都很好,但是命令 PasteTemplate 仅在选择更改时触发,并且每次单击该项目时我都需要触发它。如果我将 EventName 更改为列表中的一个 (https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.aspx),例如 MouseDown,则该命令根本不会触发。

【问题讨论】:

    标签: c# wpf listview eventtrigger


    【解决方案1】:

    要做到这一点,在尊重 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>
    

    在你的视图模型中,如下声明一个 ICmand 属性后,

    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 框架处理命令。

    【讨论】:

    • 这个功能对我来说 100% 我希望它会有所帮助
    【解决方案2】:

    您可以按照此处的建议处理 ListViewItem 的 PreviewMouseDown 事件:

    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。

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

    【讨论】:

      【解决方案3】:

      如果您想使用“SelectionChanged”,您可以在代码之后重置选择。只需将其添加到您的 PasteTemplate 中

      if(((ListView)sender).SelectedIndex == -1)return;
      //your code
      ((ListView)sender).SelectedIndex = -1;
      

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

      注意:您也可以使用 MouseDown,但它有点棘手。例如,如果用户没有单击您的任何项目,而是单击 ListView 内的其他位置,例如 this,它会再次触发您当前的选择。

      【讨论】:

      • 我正在使用 MVVM,所以我已将 Listview SelectedIndex 属性绑定到 SelectedTemplateIndex 变量。我的代码:XAML:SelectedIndex="{Binding SelectedTemplateIndex}" ViewModel:-1) return; LeaveCommentBox = SelectedCommentTemplate.Description; 987654326 -1) return; LeaveCommentBox = SelectedCommentTemplate.Description; 987654327 @和我看到了相同的行为 - 只有在选择实际更改时才会触发命令。 span>
      • SelectedTemplateIndex=-1 应该重置您的选择。它选择 -1st 元素(在列表视图中,这意味着什么都不选择)并让您再次选择。如果它仍未重置,您可以尝试重置您的 SelectedItem 或检查此link
      猜你喜欢
      • 2019-04-30
      • 2011-07-23
      • 2013-04-12
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多