Me gustaría seleccionar un nodo WPF TreeView haciendo clic derecho, justo antes de que se muestre el ContextMenu.
Para WinForms, podría usar un código como este Buscar nodo en el que se hace clic en el menú contextual , ¿cuáles son las alternativas de WPF?
wpf
treeview
contextmenu
alex2k8
fuente
fuente
if (treeViewItem == null) treeView.SelectedIndex = -1
otreeView.SelectedItem = null
. Creo que cualquiera debería funcionar.Si desea una solución solo de XAML, puede usar Blend Interactivity.
Suponga que los
TreeView
datos están vinculados a una colección jerárquica de modelos de vista que tienen unaBoolean
propiedadIsSelected
y unaString
propiedadName
, así como una colección de elementos secundarios nombradosChildren
.Hay dos partes interesantes:
La
TreeViewItem.IsSelected
propiedad está vinculada a laIsSelected
propiedad en el modelo de vista. Establecer laIsSelected
propiedad en el modelo de vista en verdadero seleccionará el nodo correspondiente en el árbol.Cuando se
PreviewMouseRightButtonDown
dispara en la parte visual del nodo (en este ejemplo aTextBlock
), laIsSelected
propiedad del modelo de vista se establece en verdadera. Volviendo a 1., puede ver que el nodo correspondiente en el que se hizo clic en el árbol se convierte en el nodo seleccionado.Una forma de obtener Blend Interactivity en su proyecto es usar el paquete NuGet Unofficial.Blend.Interactivity .
fuente
i
yei
y en qué ensamblados se pueden encontrar. Supongo:xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
yxmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
, que se encuentran en los ensamblados System.Windows.Interactivity y Microsoft.Expression.Interactions respectivamente.ChangePropertyAction
está intentando establecer unaIsSelected
propiedad del objeto de datos vinculado, que no forma parte de la interfaz de usuario, por lo que no tieneIsSelected
propiedad. ¿Estoy haciendo algo mal?IsSelected
propiedad como se indica en el segundo párrafo de mi respuesta: Suponga que losTreeView
datos están vinculados a una colección jerárquica de modelos de vista que tienen una propiedad booleanaIsSelected
... (mi énfasis).Usando "item.Focus ();" no parece funcionar al 100%, usando "item.IsSelected = true;" hace.
fuente
En XAML, agregue un controlador PreviewMouseRightButtonDown en XAML:
Luego maneja el evento de esta manera:
fuente
Usando la idea original de alex2k8, manejando correctamente los elementos no visuales de Wieser Software Ltd, el XAML de Stefan, el IsSelected de Erlend, y mi contribución de hacer verdaderamente genérico el método estático:
XAML:
Código C # detrás:
Editar: el código anterior siempre funcionó bien para este escenario, pero en otro escenario VisualTreeHelper.GetParent devolvió nulo cuando LogicalTreeHelper devolvió un valor, así que lo solucionó.
fuente
Casi correcto , pero debes tener cuidado con los elementos no visuales en el árbol (como
Run
, por ejemplo).fuente
Creo que registrar un controlador de clase debería ser suficiente. Simplemente registre un controlador de eventos enrutados en PreviewMouseRightButtonDownEvent de TreeViewItem en su archivo de código app.xaml.cs como este:
fuente
Otra forma de resolverlo usando MVVM es el comando de enlace para hacer clic derecho en su modelo de vista. Allí puede especificar otra lógica además de
source.IsSelected = true
. Esto usa soloxmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
deSystem.Windows.Interactivity
.XAML para ver:
Ver modelo:
fuente
Tenía un problema al seleccionar niños con un método HierarchicalDataTemplate. Si selecciono al hijo de un nodo, de alguna manera seleccionaría al padre raíz de ese hijo. Descubrí que el evento MouseRightButtonDown se llamaría para todos los niveles que tenía el niño. Por ejemplo, si tienes un árbol parecido a esto:
Elemento 1
- Niño 1
- Niño 2
- Subitem1
- Subitemm2
Si seleccioné Subitem2, el evento se dispararía tres veces y se seleccionaría el elemento 1. Resolví esto con una llamada booleana y asincrónica.
Se siente un poco complicado, pero básicamente configuro el booleano en verdadero en la primera pasada y lo restablezco en otro hilo en unos segundos (3 en este caso). Esto significa que el siguiente pasa por donde intentaría moverse hacia arriba, el árbol se saltará, dejándolo con el nodo correcto seleccionado. Parece funcionar hasta ahora :-)
fuente
MouseButtonEventArgs.Handled
entrue
. Dado que el niño es el primero en ser llamado. Si configura esta propiedad en true, se inhabilitarán otras llamadas al padre.Puede seleccionarlo con el evento on mouse down. Eso activará la selección antes de que se active el menú contextual.
fuente
Si desea permanecer dentro del patrón MVVM, puede hacer lo siguiente:
Ver:
Código detrás:
ViewModel:
Ahora puede reaccionar al cambio de propiedad de ClickedTreeElement o puede usar un comando que funcione internamente con ClickedTreeElement.
Vista extendida:
fuente