it-swarm.com.de

Wie erfassen Sie einen Mausklick auf ein Element in einer ListBox in WPF?

Ich möchte benachrichtigt werden, wenn ein Element in einer ListBox mit der Maus angeklickt wird, ob es bereits ausgewählt ist oder nicht.

Ich suchte und fand das: ( http://kevin-berridge.blogspot.com/2008/06/wpf-listboxitem-double-click.html siehe die Kommentare)

private void AddDoubleClickEventStyle(ListBox listBox, MouseButtonEventHandler mouseButtonEventHandler)
{
    if (listBox.ItemContainerStyle == null)
        listBox.ItemContainerStyle = new Style(typeof(ListBoxItem));
    listBox.ItemContainerStyle.Setters.Add(new EventSetter()
    {
        Event = MouseDoubleClickEvent,
        Handler = mouseButtonEventHandler
    });
}

//Usage:
AddDoubleClickEventStyle(listView1, new MouseButtonEventHandler(listView1_MouseDoubleClick));

Das funktioniert, tut es aber für ein DoubleClick. Ich kann es jedoch nicht mit einem einzigen Klick zum Laufen bringen. Ich habe MouseLeftButtonDownEvent ausprobiert - da scheint es kein MouseClick-Ereignis zu geben, aber es wird nicht aufgerufen.

Eine etwas allgemeinere Nebenfrage: Wie kann ich sehen, welche Ereignisse existieren und welche Handler ihnen entsprechen und wann sie tatsächlich etwas tun? Was sagt mir zum Beispiel, dass ich für eine MouseDoubleClickEvent eine MouseButtonEventHandler brauche? Vielleicht für eine MouseLeftButtonDownEvent ich brauche einen anderen Handler und deshalb funktioniert es nicht?

Ich habe auch die Unterklasse ListBoxItem ausprobiert und OnMouseLeftButtonDown überschrieben - aber es wird auch nicht aufgerufen.

Marc

32
marc40000

Ich glaube, dass Ihr MouseLeftButtonDown-Handler nicht aufgerufen wird, da die ListBox dieses Ereignis intern verwendet, um das SelectionChanged-Ereignis auszulösen (mit dem Gedanken, dass SelectionChanged in der überwiegenden Mehrzahl der Fälle alles ist, was Sie brauchen). Das heißt, Sie haben mehrere Möglichkeiten.

Zunächst können Sie stattdessen das Ereignis PreviewLeftButtonDown abonnieren. Bei den meisten Routingereignissen wird Bubbling als Routing-Strategie verwendet. Das bedeutet, dass das Steuerelement, das das Ereignis generiert hat, dieses zuerst erhält und das Ereignis nicht verarbeitet wird, das sich im visuellen Baum nach oben bewegt, sodass jedes Steuerelement die Möglichkeit hat, das Ereignis zu verarbeiten. Die Preview-Events hingegen sind Tunneling. Dies bedeutet, dass sie an der Wurzel des visuellen Baums beginnen (im Allgemeinen Window) und sich bis zum Steuerelement bewegen, das das Ereignis generiert hat. Da Ihr Code die Möglichkeit erhalten könnte, das Ereignis vor der ListBoxItem zu behandeln, wird dies ausgelöst (und nicht verarbeitet), sodass der Ereignishandler aufgerufen wird. Sie können diese Option implementieren, indem Sie MouseDoubleClickEvent in Ihrem Beispiel durch PreviewMouseLeftButtonDown ersetzen.

Die andere Option ist das Registrieren eines Klassenhandlers, der benachrichtigt wird, wenn eine ListBoxItem das MouseLeftButtonDown-Ereignis auslöst. Das wird so gemacht:

EventManager.RegisterClassHandler(typeof(ListBoxItem),
    ListBoxItem.MouseLeftButtonDownEvent,
    new RoutedEventHandler(this.MouseLeftButtonDownClassHandler));

private void OnMouseLeftButtonDown(object sender, RoutedEventArgs e)
{
}

Klassenhandler werden vor allen anderen Ereignishandlern aufgerufen. Sie werden jedoch für alle Steuerelemente des angegebenen Typs in Ihrer gesamten Anwendung aufgerufen. Wenn Sie also zwei ListBoxes haben, wird dieser Event-Handler aufgerufen, sobald Sie auf eine ListBoxItem klicken.

Bei Ihrer zweiten Frage können Sie am besten wissen, welche Art von Ereignishandler Sie für ein bestimmtes Ereignis benötigen, und die Liste der für ein bestimmtes Steuerelement verfügbaren Ereignisse anzeigen, indem Sie die MSDN-Dokumentation verwenden. Die Liste aller von ListBoxItem behandelten Ereignisse befindet sich beispielsweise unter http://msdn.Microsoft.com/en-us/library/system.windows.controls.listboxitem_events.aspx . Wenn Sie für ein Ereignis auf den Link klicken, enthält es den Typ des Ereignishandlers für dieses Ereignis.

48
Andy

Ich denke, Andys erste Antwort auf die Verwendung von PreviewMouseLeftButtonDown ist der Weg, dies zu tun. In XAML würde es so aussehen:

<ListBox Name="testListBox">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_MouseLeftButtonDown" />
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
17
RandomEngy

Es gibt auch eine andere Möglichkeit - das PreviewMouseDown -Ereignis zu behandeln und zu prüfen, ob es durch das Listenelement ausgelöst wurde:

In XAML:

<ListBox PreviewMouseDown="PlaceholdersListBox_OnPreviewMouseDown"/> 

Im Codebehind:

private void PlaceholdersListBox_OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var item = ItemsControl.ContainerFromElement(sender as ListBox, e.OriginalSource as DependencyObject) as ListBoxItem;
    if (item != null)
    {
        // ListBox item clicked - do some cool things here
    }
}

Wurde von this answer inspiriert, aber es wird Listbox nach Namen verwendet. Ich schlage vor, das Argument des Senders zu verwenden, um unnötige Abhängigkeiten zu vermeiden.

13
Pavel K

Es gibt eine andere Möglichkeit, das MouseDown-Ereignis in ListBox abzurufen. Sie können Event-Handler für Ereignisse hinzufügen, die als behandelt markiert sind, indem Sie die handledEventsToo-Signatur der AddHandler-Methode verwenden:

myListBox.AddHandler(UIElement.MouseDownEvent, 
        new MouseButtonEventHandler(ListBox_MouseDown), true);

Der dritte Parameter oben ist handledEventsToo, der sicherstellt, dass dieser Handler unabhängig davon aufgerufen wird, ob er bereits als Handled markiert ist (was ListBoxItem in ListBox tut).
Weitere Informationen finden Sie unter Routed Events als behandelt und Klassenbehandlung .
Siehe zum Beispiel So fügen Sie ein MouseDown-Ereignis in ListBox an.

9
zendar

Sie können das SelectionChangedEventArgs-Argument des SelectionChanged-Ereignisses verwenden, um herauszufinden, welches Element durch AddedItems und RemovedItems hinzugefügt oder entfernt wird. In der Regel wird nur das letzte angeklickt. Wenn nicht, schauen Sie sich das letzte Element an, das count-1 ist.

0
amirhp

Sie können Event="MouseLeftButtonUp" verwenden
Im Gegensatz zu "PreviewLeftButtonDown" wird auch das ListBoxItem behandelt.

0
elig