WPF ListView: (आइटम पर) ईवेंट पर डबल-क्लिक करना


85

मेरे पास निम्नलिखित हैं 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>

मैं हर बाध्य आइटम पर एक घटना कैसे जोड़ सकता हूं जो आइटम पर डबल-क्लिक करने पर आग लगाएगा?

जवाबों:


101

यहां से समाधान मिला: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/3d0eaa54-09a9-4c51-8677-8e9057777bac/


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
}

13
यदि आपको शैली को फिर से उपयोग करने की आवश्यकता नहीं है, तो आप इसे सीधे <ListView.Resources /> अनुभाग में डाल सकते हैं और एक्स को हटा सकते हैं।
डेविड श्मिट

8
यह मेरे लिए भी काम किया। धन्यवाद! BTW, आप संभवत: अपने हैंडलर के भीतर डबलक्लिक इवेंट के बबलिंग को सेट करके रोकना चाहेंगे: e.andand = true;
टॉम ए

1
मुझे इससे समस्या है। यही है, मैं x का उपयोग करता हूं: सभी UI तत्वों को स्टाइल करने के लिए विंडो में की-लेस स्टाइल, उस विंडो पर कस्टम नियंत्रण में उपयोग किए जाने वाले लिस्ट व्यू सहित। इस ईवेंट-हैंडलर को कस्टम कंट्रोल के xaml में डाल देने से विंडो में लागू किया गया स्टाइल निष्क्रिय हो जाता है।
जेनो सेसपोर 16

8
जिज्ञासा से बाहर, क्या ऐसा करने का एक और तरीका है जो MVVM का उल्लंघन नहीं करता है?
डेव

13
एक चेतावनी के रूप में: कैन का उपयोग EventSetterकरने से मेमोरी लीक हो सकती है अगर उसके हैंडलर का लक्ष्य इससे अधिक समय तक रहता है ListViewItem। मैंने पिछले कुछ दिनों को एक गंभीर मेमोरी लीक (एक समय में 20mb) डिबगिंग में बिताया, केवल यह पता लगाने के लिए कि ListViewItemएस और उनकी संबंधित मेमोरी एक के माध्यम से लीक हो रही थी EventSetter
जैच जॉनसन

69

कोई मेमोरी लीक नहीं (प्रत्येक आइटम को बंद करने की आवश्यकता नहीं है) , ठीक काम करता है:

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!");
        }
    }

1
उत्कृष्ट, मेमोरी लीक के बारे में अधिक चिंता करने की आवश्यकता नहीं है, और स्पष्ट रूप से यह बहुत क्लीनर का एक नरक है।
.555533

3
यह पर्याप्त नहीं है यदि आपकी सूची में कोई जटिल ऑब्जेक्ट है। माता-पिता की सूची देखने के लिए आपको एक दृश्य ट्री हेल्पर का उपयोग करने की आवश्यकता है। यह देखने के लिए और वहां से आप
डेटासोनेट

3
साफ और सरल। धन्यवाद।
शाश्वत

1
बहुत अच्छा और मददगार। मेरे मामले में मेरे पास अतिरिक्त चयन बटन है जो चयन क्रिया करता है। 'MouseDoubleClick = "SelectBtn_Click"' 'निजी शून्य SelectBtn_Click (वस्तु प्रेषक, RoutedEventArgs ई) {}': इस प्रकार है तो मैं डबल क्लिक इस्तेमाल किया
किशोर

3
यही कारण है कि आप हमेशा स्वीकृत उत्तर को स्क्रॉल करते हैं। बस मामले में ...
aggsol

7

मेरा समाधान @ 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'डेटाकंटेक्स्ट बाइंडिंग' ( Trackइस मामले में) मिलता है। चयनित आइटम काम करता है क्योंकि डबल-क्लिक का पहला क्लिक इसे चुनता है।


4

ज्यादातर एमवीवीएम पैटर्न को बनाए रखने के इच्छुक लोगों के लिए, मैंने काम करने के लिए एंड्रियास ग्रीच के उत्तर का उपयोग किया ।

मूल प्रवाह:

उपयोगकर्ता डबल-क्लिक आइटम -> कोड के पीछे इवेंट हैंडलर -> दृश्य मॉडल में ICommand

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संपत्ति तक पहुंच हो ।


3

आपके उदाहरण में आप यह देखने की कोशिश कर रहे हैं कि आपके ListView में किसी आइटम का चयन किया जाता है या किसी कॉलम हेडर पर क्लिक किया जाता है? यदि यह पूर्व है तो आप एक चयन हैंडलर जोड़ देंगे।

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

यदि यह बाद की बात है तो आपको डबल क्लिक का पता लगाने और उचित कार्रवाई करने के लिए GridViewColumn आइटम पर MouseLeftButtonUp या MouseLeftButtonDown घटनाओं के कुछ संयोजन का उपयोग करना होगा। वैकल्पिक रूप से आप GridView की घटनाओं को संभाल सकते हैं और वहां से काम कर सकते हैं जो माउस के नीचे कॉलम हेडर था।


मैं बंधी वस्तुओं पर एक घटना चाहता था, हेडर नहीं
एंड्रियास ग्रीच

मेरे लिए यह एक नई बात है। अपना जवाब डालने के लिए धन्यवाद (और मैं अपना कोई भी डबलक्लिक इवेंट स्टेटमेंट नहीं निकालूंगा)।
एरॉन क्लॉसन

3

वैकल्पिक जो मैंने उपयोग किया है, वह ईवेंट टू कमांड है,

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

1

ईपॉक्सी_ डाइऑक्साइड के उत्तर पर बिल्डिंग , मैंने त्रुटियों से बचने के लिए एक जांच में जोड़ा जब ग्रिड व्यूकोल्यूम हेडर में डबल क्लिक करना।

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

बहुत शांत - PowerShell- साथ काम करता है $myListView.Add_MouseDoubleClick({ Param($sender, $ev); $e = [System.Windows.Input.MouseButtonEventArgs]$ev; $itemData = ([System.Windows.FrameworkElement]$e.OriginalSource).DataContext }); if ($item -ne $null) { Write-Host $itemData; } })--- कास्टिंग की आवश्यकता नहीं है लेकिन आईएसई में मदद करता है पूरा होने पाने के लिए
BananaAcid
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.