C# WPF ListView:附加双击(在项目上)事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/728205/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF ListView: Attaching a double-click (on an item) event
提问by Andreas Grech
I have the following ListView
:
我有以下几点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>
How can I attach an event to every bound item that will fire on double-clicking the item?
如何将事件附加到双击项目时将触发的每个绑定项目?
采纳答案by Andreas Grech
Found the solution from here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3d0eaa54-09a9-4c51-8677-8e90577e7bac/
从这里找到解决方案:http: //social.msdn.microsoft.com/Forums/en-US/wpf/thread/3d0eaa54-09a9-4c51-8677-8e90577e7bac/
XAML:
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#:
C#:
protected void HandleDoubleClick(object sender, MouseButtonEventArgs e)
{
var track = ((ListViewItem) sender).Content as Track; //Casting back to the binded Track
}
回答by sipwiz
In your example are you trying to catch when an item in your ListView is selected or when a column header is clicked on? If it's the former you would add a SelectionChanged handler.
在您的示例中,您是否试图在选择 ListView 中的项目或单击列标题时进行捕获?如果是前者,您将添加一个 SelectionChanged 处理程序。
<ListView Name="TrackListView" SelectionChanged="MySelectionChanged">
If it's the latter you would have to use some combination of MouseLeftButtonUp or MouseLeftButtonDown events on the GridViewColumn items to detect a double click and take appropriate action. Alternatively you could handle the events on the GridView and work out from there which column header was under the mouse.
如果是后者,则必须在 GridViewColumn 项目上使用 MouseLeftButtonUp 或 MouseLeftButtonDown 事件的某种组合来检测双击并采取适当的操作。或者,您可以处理 GridView 上的事件,并从那里算出鼠标下方的列标题。
回答by epox
No memory leaks, works fine:
没有内存泄漏,工作正常:
XAML:
XAML:
<ListView ItemsSource="{Binding TrackCollection}" MouseDoubleClick="ListView_MouseDoubleClick" />
C#:
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!");
}
}
回答by CAD bloke
My solution was based on @epox_sub's answerwhich you should look at for where to put the Event Handler in the XAML. The code-behind didn't work for me because my ListViewItems
are complex objects. @sipwiz's answerwas a great hint for where to look...
我的解决方案基于@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!");
}
}
The bonus with this is you get the SelectedItem
's DataContext binding (Track
in this case). Selected Item works because the first click of the double-click selects it.
这样做的好处是您可以获得SelectedItem
的 DataContext 绑定(Track
在这种情况下)。Selected Item 有效,因为双击的第一次单击将它选中。
回答by Kramer
Building on epox_spb's answer, I added in a check to avoid errors when double clicking in the GridViewColumn headers.
基于epox_spb 的回答,我添加了一个检查以避免在双击 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!");
}
}
回答by Micah Vertal
For those interested in mostly maintaining the MVVM pattern, I used Andreas Grech's answerto make a work-around.
对于那些主要对维护 MVVM 模式感兴趣的人,我使用Andreas Grech 的答案来解决问题。
Basic flow:
User double-clicks item -> Event handler in code behind -> ICommand in view model
基本流程:
用户双击项目 -> 隐藏代码中的事件处理程序 -> 视图模型中的 ICommand
ProjectView.xaml:
项目视图.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:
项目视图.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:
项目视图模型.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 can be found here.
可以在此处找到 DelegateCommand.cs 。
In my instance, I have a collection of Project
objects that populate the ListView
. These objects contain more properties than are shown in the list, and I open a ProjectDetailView
(a WPF Window
) to display them.
在我的例子中,我有一组Project
填充ListView
. 这些对象包含的属性比列表中显示的要多,我打开一个ProjectDetailView
(一个 WPF Window
)来显示它们。
The sender
object of the event handler is the selected ListViewItem
. Subsequently, the Project
that I want access to is contained within the Content
property.
sender
事件处理程序的对象是 selected ListViewItem
。随后,Project
我想要访问的 包含在该Content
属性中。
回答by Code Name Hyman
Alternative that I used is Event To Command,
我使用的替代方法是 Event To Command,
<ListView ItemsSource="{Binding SelectedTrack}" SelectedItem="{Binding SelectedTrack}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding SelectTrackCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...........
...........
</ListView>