¿Cómo puedo recuperar el elemento seleccionado en una vista de árbol WPF? Quiero hacer esto en XAML, porque quiero vincularlo.
Puede pensar que es, SelectedItem
pero aparentemente eso no existe, es de solo lectura y, por lo tanto, inutilizable.
Esto es lo que quiero hacer:
<TreeView ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource ClusterTemplate}"
SelectedItem="{Binding Path=Model.SelectedCluster}" />
Quiero vincular SelectedItem
a una propiedad en mi modelo.
Pero esto me da el error:
La propiedad 'SelectedItem' es de solo lectura y no se puede establecer desde el marcado.
Editar: Ok, esta es la forma en que resolví esto:
<TreeView
ItemsSource="{Binding Path=Model.Clusters}"
ItemTemplate="{StaticResource HoofdCLusterTemplate}"
SelectedItemChanged="TreeView_OnSelectedItemChanged" />
y en el código detrás del archivo de mi xaml:
private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
Model.SelectedCluster = (Cluster)e.NewValue;
}
Respuestas:
Me doy cuenta de que ya se ha aceptado una respuesta, pero la armé para resolver el problema. Utiliza una idea similar a la solución de Delta, pero sin la necesidad de subclasificar TreeView:
Luego puede usar esto en su XAML como:
¡Ojalá ayude a alguien!
fuente
{Binding SelectedItem, Mode=TwoWay}
con{Binding MyViewModelField, Mode=TwoWay}
xmlns:e="http://schemas.microsoft.com/expression/2010/interactivity"
Esta propiedad existe: TreeView.SelectedItem
Pero es de solo lectura, por lo que no puede asignarlo a través de un enlace, solo recuperarlo
fuente
TreeView.SelectedItem
afecte una propiedad en el modelo cuando el usuario selecciona un elemento (también conocido comoOneWayToSource
)?Responda con propiedades adjuntas y sin dependencias externas, en caso de que surja la necesidad.
Puede crear una propiedad adjunta que sea enlazable y tenga un captador y definidor:
Agregue la declaración de espacio de nombres que contiene esa clase a su XAML y enlace de la siguiente manera (local es como denominé la declaración de espacio de nombres):
Ahora puede vincular el elemento seleccionado y también configurarlo en su modelo de vista para cambiarlo programáticamente, en caso de que surja ese requisito. Esto es, por supuesto, suponiendo que implemente INotifyPropertyChanged en esa propiedad en particular.
fuente
Bueno, encontré una solución. Mueve el desorden, por lo que MVVM funciona.
Primero agregue esta clase:
y agregue esto a su xaml:
fuente
Responde un poco más de lo que espera el OP ... Pero espero que al menos pueda ayudar a alguien.
Si desea ejecutar un comando
ICommand
cada vez que seSelectedItem
modifica, puede vincular un comando en un evento y ya no es necesario usar una propiedadSelectedItem
en elViewModel
Para hacerlo:
1- Añadir referencia a
System.Windows.Interactivity
2- Vincula el comando al evento
SelectedItemChanged
fuente
System.Windows.Interactivity
se puede instalar desde NuGet: nuget.org/packages/System.Windows.Interactivity.WPFSystem.Windows.Interactivity
. Me funcionó (probé con el proyecto .NET Core). Para configurar las cosas, simplemente agregue el paquete nuget Microsoft.Xaml.Behaviors.Wpf , cambie el espacio de nombres axmlns:i="http://schemas.microsoft.com/xaml/behaviors"
. Para obtener más información, consulte el blogEsto se puede lograr de una manera 'más agradable' usando solo el enlace y EventToCommand de la biblioteca de GalaSoft MVVM Light. En su VM, agregue un comando que se llamará cuando se cambie el elemento seleccionado, e inicialice el comando para realizar cualquier acción que sea necesaria. En este ejemplo, utilicé un RelayCommand y solo estableceré la propiedad SelectedCluster.
Luego agregue el comportamiento EventToCommand en su xaml. Esto es realmente fácil usando la mezcla.
fuente
Todo complicado ... Ve con Caliburn Micro (http://caliburnmicro.codeplex.com/)
Ver:
ViewModel:
fuente
Encontré esta página buscando la misma respuesta que el autor original, y demostrando que siempre hay más de una forma de hacerlo, la solución para mí fue aún más fácil que las respuestas proporcionadas aquí hasta ahora, así que pensé que también podría agregar a la pila
La motivación para el enlace es mantenerlo agradable y MVVM. El uso probable de ViewModel es tener una propiedad con un nombre como "CurrentThingy", y en otro lugar, el DataContext en otra cosa está vinculado a "CurrentThingy".
En lugar de seguir los pasos adicionales requeridos (por ejemplo: comportamiento personalizado, control de terceros) para admitir un enlace agradable desde TreeView a mi Modelo, y luego de otra cosa a mi Modelo, mi solución fue usar el enlace de Elemento simple. TreeView.SelectedItem, en lugar de vincular la otra cosa a mi ViewModel, omitiendo así el trabajo adicional requerido.
XAML:
Por supuesto, esto es excelente para leer el elemento seleccionado actualmente, pero no para configurarlo, que es todo lo que necesitaba.
fuente
También puede usar la propiedad TreeViewItem.IsSelected
fuente
También hay una manera de crear la propiedad XAML bindable SelectedItem sin usar Interaction.Behaviors.
Luego puede usar esto en su XAML como:
fuente
Intenté todas las soluciones de estas preguntas. Nadie resolvió mi problema por completo. Así que creo que es mejor usar una clase heredada con la propiedad redefinida SelectedItem. Funcionará perfectamente si elige el elemento de árbol de la GUI y si establece el valor de esta propiedad en su código
fuente
Mi requisito era una solución basada en PRISM-MVVM donde se necesitaba un TreeView y el objeto vinculado es del tipo Colección <> y, por lo tanto, necesita HierarchicalDataTemplate. El BindableSelectedItemBehavior predeterminado no podrá identificar el TreeViewItem secundario. Para que funcione en este escenario.
Esto permite recorrer todos los elementos independientemente del nivel.
fuente
Sugiero una adición al comportamiento proporcionado por Steve Greatrex. Su comportamiento no refleja los cambios de la fuente porque puede no ser una colección de TreeViewItems. Por lo tanto, se trata de encontrar el TreeViewItem en el árbol cuyo datacontext es el Valor seleccionado de la fuente. TreeView tiene una propiedad protegida llamada "ItemsHost", que contiene la colección TreeViewItem. Podemos obtenerlo a través de la reflexión y caminar por el árbol buscando el elemento seleccionado.
De esta manera, el comportamiento funciona para enlaces bidireccionales. Alternativamente, es posible mover la adquisición de ItemsHost al método OnAttached de Behavior, ahorrando la sobrecarga de usar la reflexión cada vez que se actualiza el enlace.
fuente
WPF MVVM TreeView SelectedItem
... es una mejor respuesta, pero no menciona una manera de obtener / establecer el SelectedItem en ViewModel.
fuente
Después de estudiar Internet por un día, encontré mi propia solución para seleccionar un elemento después de crear una vista de árbol normal en un entorno WPF / C # normal
fuente
También se puede hacer usando la propiedad IsSelected del elemento TreeView. Así es como lo logré,
Luego, en el ViewModel que contiene los datos a los que está vinculado su TreeView, simplemente suscríbase al evento en la clase TreeViewItem.
Y finalmente, implemente este controlador en el mismo ViewModel,
Y la encuadernación, por supuesto,
fuente
Sé que este hilo tiene 10 años, pero el problema aún existe ...
La pregunta original era "recuperar" el elemento seleccionado. También necesitaba "obtener" el elemento seleccionado en mi modelo de vista (no configurarlo). De todas las respuestas en este hilo, la de 'Wes' es la única que aborda el problema de manera diferente: si puede usar el 'Elemento seleccionado' como objetivo para el enlace de datos, úselo como fuente para el enlace de datos. Wes lo hizo en otra propiedad de vista, lo haré en una propiedad de modelo de vista:
Necesitamos dos cosas:
Viewmodel:
Ver constructor:
fuente
(Solo aceptemos que TreeView obviamente está roto con respecto a este problema. La unión a SelectedItem hubiera sido obvia. Suspiro )
Necesitaba la solución para interactuar correctamente con la propiedad IsSelected de TreeViewItem, así que así es como lo hice:
Con este XAML:
fuente
Te traigo mi solución que ofrece las siguientes características:
Soporta 2 formas vinculantes
Actualiza automáticamente las propiedades TreeViewItem.IsSelected (de acuerdo con SelectedItem)
No hay subclases TreeView
Los elementos vinculados a ViewModel pueden ser de cualquier tipo (incluso nulos)
1 / Pegue el siguiente código en su CS:
2 / Ejemplo de uso en su archivo XAML
fuente
Propongo esta solución (que considero la más fácil y sin pérdidas de memoria) que funciona perfectamente para actualizar el elemento seleccionado de ViewModel desde el elemento seleccionado de View.
Tenga en cuenta que cambiar el elemento seleccionado de ViewModel no actualizará el elemento seleccionado de la Vista.
Uso de XAML
fuente