programing

WPF ListView : 항목에서 두 번 클릭 이벤트 첨부

nasanasas 2020. 10. 7. 07:44
반응형

WPF 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>

항목을 두 번 클릭 할 때 발생하는 모든 바인딩 된 항목에 이벤트를 어떻게 첨부 할 수 있습니까?


여기에서 솔루션을 찾았습니다. 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>

씨#:

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

메모리 누수가없고 잘 작동합니다.

XAML :

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

씨#:

    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.ToString()+" Double Click handled!");
    }
}

이것의 보너스는 당신이 SelectedItem의 DataContext 바인딩 을 얻는 것입니다 ( Track이 경우). 선택한 항목은 두 번 클릭의 첫 번째 클릭이 항목을 선택하기 때문에 작동합니다.


귀하의 예에서 ListView의 항목이 선택되거나 열 머리글이 클릭 될 때 포착하려고합니까? 전자 인 경우 SelectionChanged 처리기를 추가합니다.

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

후자의 경우 GridViewColumn 항목에서 MouseLeftButtonUp 또는 MouseLeftButtonDown 이벤트의 일부 조합을 사용하여 두 번 클릭을 감지하고 적절한 조치를 취해야합니다. 또는 GridView에서 이벤트를 처리하고 마우스 아래에있는 열 머리글을 확인할 수 있습니다.


주로 MVVM 패턴을 유지하는 데 관심이있는 사람들을 위해 Andreas Grech의 답변 을 사용하여 해결 방법을 만들었습니다.

기본 흐름 :

User double-clicks 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 can be found here.

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.

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.


Building on epox_spb's answer, I added in a check to avoid errors when double clicking in the GridViewColumn headers.

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

참고URL : https://stackoverflow.com/questions/728205/wpf-listview-attaching-a-double-click-on-an-item-event

반응형