programing

WPF 목록 보기:(항목에) 더블 클릭 이벤트 첨부

bestprogram 2023. 4. 12. 23:05

WPF 목록 보기:(항목에) 더블 클릭 이벤트 첨부

다음과 같은 것이 있습니다.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!");
        }
    }

내 솔루션은 XAML에서 이벤트 핸들러를 어디에 배치해야 하는지 살펴봐야 하는 @epox_sub의 답변을 기반으로 했습니다. 코드 배후에 있는 것은 내 코드에 문제가 있었기 때문입니다.ListViewItems복잡한 객체입니다.@hargwiz의 대답은 어디를 봐야 할지 알려주는 큰 힌트였다...

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

이것으로 얻을 수 있는 보너스는SelectedItem의 Data Context 바인딩(Track(이 경우)를 참조해 주세요.선택한 항목은 두 번 클릭하면 선택되기 때문에 작동합니다.

제가 사용한 대안은 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>

MVVM 패턴을 주로 유지 보수하는 데 관심이 있는 분들을 위해 Andreas Grech의 답변을 참고하여 해결 방법을 제시했습니다.

기본 흐름:

사용자가 아이템을 더블클릭 -> 코드의 이벤트 핸들러 -> 뷰모델의 ICMand를 더블클릭합니다.

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 는, 여기를 참조해 주세요.

제 경우엔, 제가 가지고 있는 컬렉션이 있습니다.Project를 채우는 오브젝트ListView이러한 오브젝트에는 목록에 표시된 것보다 더 많은 속성이 포함되어 있으며,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의 항목이 선택되었을 때 또는 열 헤더가 클릭되었을 때 캡처하려고 합니까?Selection Changed 핸들러를 추가합니다.

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

후자의 경우 GridViewColumn 항목에서 MouseLeftButtonUp 또는 MouseLeftButtonDown 이벤트 조합을 사용하여 더블클릭을 검출하고 적절한 액션을 수행해야 합니다.또는 GridView에서 이벤트를 처리하고 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!");
    }
}

물론 당신의 setter/getter 클래스 이름이 될 것입니다.

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