XAML WPF列表视图:附加双击(项目)事件

jrcvhitl  于 2023-06-19  发布在  其他
关注(0)|答案(8)|浏览(157)

下面是ListView

<ListView Name="TrackListView">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Title" Width="100" 
                            HeaderTemplate="{StaticResource BlueHeader}" 
                            DisplayMemberBinding="{Binding Name}"/>

            <GridViewColumn Header="Artist" Width="100"  
                            HeaderTemplate="{StaticResource BlueHeader}"  
                            DisplayMemberBinding="{Binding Album.Artist.Name}" />
        </GridView>
    </ListView.View>
</ListView>

如何将事件附加到每个绑定项上,使其在双击该项时触发?

pdsfdshx

pdsfdshx1#

从这里找到解决方案:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3d0eaa54-09a9-4c51-8677-8e90577e7bac/
XAML:

<UserControl.Resources>
    <Style x:Key="itemstyle" TargetType="{x:Type ListViewItem}">
        <EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClick" />
    </Style>
</UserControl.Resources>

<ListView Name="TrackListView" ItemContainerStyle="{StaticResource itemstyle}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Title" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Artist" Width="100" HeaderTemplate="{StaticResource BlueHeader}" DisplayMemberBinding="{Binding Album.Artist.Name}" />
        </GridView>
    </ListView.View>
</ListView>

C#:

protected void HandleDoubleClick(object sender, MouseButtonEventArgs e)
{
    var track = ((ListViewItem) sender).Content as Track; //Casting back to the binded Track
}
jc3wubiy

jc3wubiy2#

没有内存泄漏 (无需取消订阅每个项目),工作正常:
XAML:

<ListView MouseDoubleClick="ListView_MouseDoubleClick" ItemsSource="{Binding TrackCollection}" />

C#:

void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        var item = ((FrameworkElement) e.OriginalSource).DataContext as Track;
        if (item != null)
        {
            MessageBox.Show("Item's Double Click handled!");
        }
    }
im9ewurl

im9ewurl3#

我的解决方案是基于@epox_sub的答案,您应该查看将事件处理程序放置在XAML中的位置。代码隐藏对我不起作用,因为我的ListViewItems是复杂对象。@sipwiz的回答是一个很好的提示,让我们看看……

void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var item = ListView.SelectedItem as Track;
    if (item != null)
    {
      MessageBox.Show(item + " Double Click handled!");
    }
}

这样做的好处是您可以获得SelectedItem的DataContext绑定(本例中为Track)。“选定项”起作用,因为双击的第一次单击会选中它。

hjqgdpho

hjqgdpho4#

如果安装了Microsoft.Xaml.Behaviours.WPF包,则可以使用MVVM。
一旦你安装了这个包,你就可以在你的XAML中引用它,如下所示:

xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

然后,您可以将以下内容添加到ListView中,这样可以将视图模型中的命令绑定到鼠标双击事件。

<ListView 
    x:Name="ListView" 
    ItemsSource="{Binding SelectedTrack}" SelectedItem="{Binding SelectedTrack}" >
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="MouseDoubleClick">
            <i:InvokeCommandAction 
                Command="{Binding SelectTrackCommand}"
                CommandParameter={Binding ElementName=ListView, Path=SelectedItems}/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
        ...........
        ...........
</ListView>

Command属性应该绑定到ViewModel中的Command实现。例如:

private CommandHandler<IList> _SelectTrackCommand;
public CommandHandler<IList> SelectTrackCommand => _SelectTrackCommand ?? (_SelectTrackCommand = new CommandHandler<IList>(items =>
            {
                SelectionChanged(items);
            }));

上面的SelectionChanged方法正在对ListView项执行某些操作。
注意:ListView项是使用XAML中的CommandParameter传入的。这是可选的,但如果您希望从Command中对SelectedItems或SelectedItem进行操作,并且不将它们绑定到ViewModel中的其他位置,则可能会很有用。

t40tm48m

t40tm48m5#

对于那些主要对维护MVVM模式感兴趣的人,我使用Andreas Grech's answer进行了变通。

基本流程:

用户双击item -> Event handler in code behind -> ICommand in view model
ProjectView.xaml:

<UserControl.Resources>
    <Style TargetType="ListViewItem" x:Key="listViewDoubleClick">
        <EventSetter Event="MouseDoubleClick" Handler="ListViewItem_MouseDoubleClick"/>
    </Style>
</UserControl.Resources>

...

<ListView ItemsSource="{Binding Projects}" 
          ItemContainerStyle="{StaticResource listViewDoubleClick}"/>

ProjectView.xaml.cs:

public partial class ProjectView : UserControl
{
    public ProjectView()
    {
        InitializeComponent();
    }

    private void ListViewItem_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        ((ProjectViewModel)DataContext)
            .ProjectClick.Execute(((ListViewItem)sender).Content);
    }
}

ProjectViewModel.cs:

public class ProjectViewModel
{
    public ObservableCollection<Project> Projects { get; set; } = 
               new ObservableCollection<Project>();

    public ProjectViewModel()
    {
        //Add items to Projects
    }

    public ICommand ProjectClick
    {
        get { return new DelegateCommand(new Action<object>(OpenProjectInfo)); }
    }

    private void OpenProjectInfo(object _project)
    {
        ProjectDetailView project = new ProjectDetailView((Project)_project);
        project.ShowDialog();
    }
}

DelegateCommand.cs可以在here中找到。
在我的示例中,我有一个Project对象的集合,它们填充了ListView。这些对象包含的属性比列表中显示的要多,我打开一个ProjectDetailView(一个WPF Window)来显示它们。
事件处理程序的sender对象是选定的ListViewItem。随后,我想要访问的Project包含在Content属性中。

syqv5f0l

syqv5f0l6#

epox_spb's answer的基础上,我添加了一个检查,以避免在GridViewColumn标题中双击时出错。

void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var dataContext = ((FrameworkElement)e.OriginalSource).DataContext;
    if (dataContext is Track)
    {
        MessageBox.Show("Item's Double Click handled!");
    }
}
gywdnpxw

gywdnpxw7#

在你的例子中,你是想捕捉ListView中的一个项目被选中的时间,还是一个列标题被点击的时间?如果是前者,则需要添加SelectionChanged处理程序。

<ListView Name="TrackListView" SelectionChanged="MySelectionChanged">

如果是后者,则必须在GridViewColumn项上使用MouseLeftButtonUp或MouseLeftButtonDown事件的某种组合来检测双击并采取适当的操作。或者,您可以在GridView上处理事件,并从那里计算出鼠标下的列标题。

qxgroojn

qxgroojn8#

如果您正在通过
ObservableCollection<ItemClass> Items类,
而上面的答案中没有一个对你有用“就像发生在我身上的事情一样”,那么就用途:

private void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    var item = ((FrameworkElement)e.OriginalSource).DataContext as ItemClass; //<< your class name here

    if (item != null)
    {
        MessageBox.Show(item.UserName + " : item Double Click handled!");
    }
}

当然,ItemClass将是您的setter/getter类名

相关问题