我有以下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>
如何将事件附加到双击项目时将触发的每个绑定项目?
答案 0 :(得分:95)
从此处找到解决方案: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
}
答案 1 :(得分:62)
没有内存泄漏,工作正常:
XAML:
<ListView ItemsSource="{Binding TrackCollection}" MouseDoubleClick="ListView_MouseDoubleClick" />
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!");
}
}
答案 2 :(得分:5)
我的解决方案基于@epox_sub's answer,您应该查看将事件处理程序放在XAML中的位置。代码隐藏对我不起作用,因为我的ListViewItems
是复杂的对象。 @sipwiz's answer是一个很好的暗示在哪里看......
void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var item = ListView.SelectedItem as Track;
if (item != null)
{
MessageBox.Show(item.ToString()+" Double Click handled!");
}
}
这样做可以获得SelectedItem
的DataContext绑定(在这种情况下为Track
)。所选项目有效,因为双击的第一次单击会选择它。
答案 3 :(得分:3)
在您的示例中,您是否尝试捕获ListView中的项目被选中或单击列标题时?如果是前者,你会添加一个SelectionChanged处理程序。
<ListView Name="TrackListView" SelectionChanged="MySelectionChanged">
如果是后者,则必须在GridViewColumn项目上使用MouseLeftButtonUp或MouseLeftButtonDown事件的某种组合来检测双击并采取适当的操作。或者,您可以处理GridView上的事件,并从那里找出哪个列标题位于鼠标下。
答案 4 :(得分:3)
对于那些对维护MVVM模式感兴趣的人,我使用Andreas Grech's answer来解决这个问题。
基本流程:
用户双击项目 - &gt;代码背后的事件处理程序 - &gt; ICommand in 查看模型
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
的{{1}}个对象。这些对象包含的属性多于列表中显示的属性,我打开ListView
(WPF ProjectDetailView
)来显示它们。
事件处理程序的Window
对象是选定的sender
。随后,我要访问的ListViewItem
包含在Project
属性中。
答案 5 :(得分:3)
我使用的替代方法是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>
答案 6 :(得分:1)
在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!");
}
}