[英]WPF ListView: Attaching a double-click (on an item) event
我有以下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>
如何將事件附加到將在雙擊項目時觸發的每個綁定項目?
從這里找到解決方案: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
}
沒有內存泄漏(無需取消訂閱每個項目) ,工作正常:
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!");
}
}
我的解決方案是基於@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
)。 所選項目有效,因為第一次單擊雙擊將其選中。
我使用的替代方法是事件到命令,
<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>
對於那些對主要維護 MVVM 模式感興趣的人,我使用了Andreas Grech 的答案來解決問題。
基本流程:
用戶雙擊項目 -> 代碼中的事件處理程序 -> 視圖模型中的 ICommand
項目視圖.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);
}
}
項目視圖模型.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。
在我的實例中,我有一個填充ListView
的Project
對象的集合。 這些對象包含的屬性比列表中顯示的要多,我打開一個ProjectDetailView
(一個 WPF Window
)來顯示它們。
事件處理程序的sender
對象是選定的ListViewItem
。 隨后,我想要訪問的Project
包含在Content
屬性中。
基於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!");
}
}
在您的示例中,您是否試圖捕捉何時選擇 ListView 中的項目或單擊列標題? 如果是前者,您將添加一個 SelectionChanged 處理程序。
<ListView Name="TrackListView" SelectionChanged="MySelectionChanged">
如果是后者,則必須在 GridViewColumn 項目上使用 MouseLeftButtonUp 或 MouseLeftButtonDown 事件的某種組合來檢測雙擊並采取適當的操作。 或者,您可以處理 GridView 上的事件並從那里計算出鼠標下方的列標題。
如果您Listview
通過
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類名稱
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.