Ich möchte einen WPF TreeView-Knoten mit der rechten Maustaste auswählen, kurz bevor das ContextMenu angezeigt wird.
Für WinForms könnte ich Code wie diesen verwenden. Klicken Sie im Kontextmenü auf den Knoten Suchen. Welche WPF-Alternativen gibt es?
wpf
treeview
contextmenu
alex2k8
quelle
quelle
if (treeViewItem == null) treeView.SelectedIndex = -1
odertreeView.SelectedItem = null
. Ich glaube, beides sollte funktionieren.Wenn Sie eine Nur-XAML-Lösung wünschen, können Sie Blend Interactivity verwenden.
Angenommen, die
TreeView
Daten sind an eine hierarchische Sammlung von Ansichtsmodellen mit einerBoolean
EigenschaftIsSelected
und einerString
EigenschaftName
sowie eine Sammlung von benannten untergeordneten Elementen gebundenChildren
.Es gibt zwei interessante Teile:
Die
TreeViewItem.IsSelected
Eigenschaft ist an dieIsSelected
Eigenschaft im Ansichtsmodell gebunden . Wenn Sie dieIsSelected
Eigenschaft im Ansichtsmodell auf true setzen, wird der entsprechende Knoten im Baum ausgewählt.Bei
PreviewMouseRightButtonDown
Bränden im visuellen Teil des Knotens (in diesem Beispiel aTextBlock
) wird dieIsSelected
Eigenschaft im Ansichtsmodell auf true gesetzt. Zurück zu 1. Sie können sehen, dass der entsprechende Knoten, auf den im Baum geklickt wurde, zum ausgewählten Knoten wird.Eine Möglichkeit, Blend Interactivity in Ihr Projekt aufzunehmen, ist die Verwendung des NuGet-Pakets Unofficial.Blend.Interactivity .
quelle
i
und dieei
Namespace-Zuordnungen aufgelöst werden und in welchen Assemblys sie gefunden werden können. Ich gehe davon aus, dass:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
undxmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
welche in den Assemblys System.Windows.Interactivity bzw. Microsoft.Expression.Interactions enthalten sind.ChangePropertyAction
versucht wird, eineIsSelected
Eigenschaft des gebundenen Datenobjekts festzulegen, das nicht Teil der Benutzeroberfläche ist, sodass es keineIsSelected
Eigenschaft hat. Mache ich etwas falsch?IsSelected
Eigenschaft hat, wie im zweiten Absatz meiner Antwort angegeben: Angenommen, dieTreeView
Daten sind an eine hierarchische Sammlung von Ansichtsmodellen mit einer booleschen EigenschaftIsSelected
gebunden ... (meine Betonung).Verwenden von "item.Focus ();" scheint nicht 100% zu funktionieren, wenn "item.IsSelected = true;" tut.
quelle
Fügen Sie in XAML einen PreviewMouseRightButtonDown-Handler in XAML hinzu:
Behandeln Sie das Ereignis dann folgendermaßen:
quelle
Unter Verwendung der ursprünglichen Idee von alex2k8, des korrekten Umgangs mit nicht visuellen Elementen von Wieser Software Ltd, der XAML von Stefan, der IsSelected von Erlend und meinem Beitrag, die statische Methode wirklich generisch zu machen:
XAML:
C # -Code dahinter:
Bearbeiten: Der vorherige Code hat in diesem Szenario immer einwandfrei funktioniert, aber in einem anderen Szenario hat VisualTreeHelper.GetParent null zurückgegeben, wenn LogicalTreeHelper einen Wert zurückgegeben hat.
quelle
Fast richtig , aber Sie müssen auf nicht visuelle Elemente im Baum achten (wie
Run
z. B. a).quelle
Ich denke, die Registrierung eines Klassenhandlers sollte den Trick machen. Registrieren Sie einfach einen gerouteten Ereignishandler im PreviewMouseRightButtonDownEvent von TreeViewItem in Ihrer app.xaml.cs-Codedatei wie folgt:
quelle
Eine andere Möglichkeit, das Problem mit MVVM zu lösen, ist der Befehl bind, mit der rechten Maustaste auf Ihr Ansichtsmodell zu klicken. Dort können Sie auch andere Logik angeben
source.IsSelected = true
. Dies wird nurxmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
von verwendetSystem.Windows.Interactivity
.XAML zur Ansicht:
Modell anzeigen:
quelle
Ich hatte ein Problem mit der Auswahl von Kindern mit einer HierarchicalDataTemplate-Methode. Wenn ich das Kind eines Knotens auswählen würde, würde es irgendwie das Stammelternteil dieses Kindes auswählen. Ich fand heraus, dass das MouseRightButtonDown-Ereignis für jedes Level aufgerufen wird, in dem sich das Kind befindet. Zum Beispiel, wenn Sie einen Baum wie diesen haben:
Punkt 1
- Kind 1
- Kind 2
- Unterpunkt1
- Unterpunkt2
Wenn ich Subitem2 auswählen würde, würde das Ereignis dreimal ausgelöst und Element 1 würde ausgewählt. Ich habe dies mit einem booleschen und einem asynchronen Aufruf gelöst.
Es fühlt sich etwas ungeschickt an, aber im Grunde habe ich den Booleschen Wert beim ersten Durchgang auf true gesetzt und ihn in wenigen Sekunden auf einen anderen Thread zurückgesetzt (in diesem Fall 3). Dies bedeutet, dass der nächste Durchgang, bei dem versucht wird, den Baum nach oben zu bewegen, übersprungen wird und Sie den richtigen Knoten ausgewählt haben. Es scheint soweit zu funktionieren :-)
quelle
MouseButtonEventArgs.Handled
zutrue
. Da ist das Kind das erste, das gerufen wird. Wenn Sie diese Eigenschaft auf true setzen, werden andere Aufrufe des übergeordneten Elements deaktiviert.Sie können es mit dem Ereignis "Mit der Maus nach unten" auswählen. Dadurch wird die Auswahl ausgelöst, bevor das Kontextmenü aktiviert wird.
quelle
Wenn Sie innerhalb des MVVM-Musters bleiben möchten, können Sie Folgendes tun:
Aussicht:
Code dahinter:
ViewModel:
Jetzt können Sie entweder auf die Änderung der ClickedTreeElement-Eigenschaft reagieren oder einen Befehl verwenden, der intern mit dem ClickedTreeElement funktioniert.
Erweiterte Ansicht:
quelle